diff options
author | David 'Digit' Turner <digit@android.com> | 2011-02-25 15:07:11 +0100 |
---|---|---|
committer | David 'Digit' Turner <digit@android.com> | 2011-03-01 15:31:11 +0100 |
commit | 25eb6557b94da066d6e137c07aeced39badf5aa6 (patch) | |
tree | ace745b614c03b9462749b1477ff0260041db618 | |
parent | 7e21ff9a2313a9e95fd5fa50bca24dbf3d3170a3 (diff) | |
download | external_qemu-25eb6557b94da066d6e137c07aeced39badf5aa6.zip external_qemu-25eb6557b94da066d6e137c07aeced39badf5aa6.tar.gz external_qemu-25eb6557b94da066d6e137c07aeced39badf5aa6.tar.bz2 |
Rework AvdInfo processing.
This patch changes the code in android/avd/info.c to prepare
for future patches that will move initialization disk images
to the core (including locking and creating temporary files).
+ Remove AvdInfo structure dependencies on many of the
functions, to make them more generic/usable.
+ Remove skin-related processing from avdInfo_new() and
avdInfo_newFromBuild().
+ Remove avdInfo_getSkinName() and avdInfo_getSkinDir(), and
replace them with a single avdInfo_getSkinInfo().
+ Rename 'qemu-hardware.ini' to 'hardware-qemu.ini' to follow
the same naming convention than the one used for disk
images (e.g. "userdata-qemu.img" and "system-qemu.img")
Change-Id: I32cb0a5850f8c0b9df93d2630552941fd2b461c1
-rw-r--r-- | android/avd/info.c | 1104 | ||||
-rw-r--r-- | android/avd/info.h | 30 | ||||
-rw-r--r-- | android/main-common.c | 101 | ||||
-rw-r--r-- | android/main-common.h | 12 | ||||
-rw-r--r-- | android/main.c | 47 |
5 files changed, 719 insertions, 575 deletions
diff --git a/android/avd/info.c b/android/avd/info.c index 81d848d..5f110d3 100644 --- a/android/avd/info.c +++ b/android/avd/info.c @@ -84,6 +84,11 @@ AvdInfo* android_avdInfo; */ #define SKIN_PATH "skin.path" +/* the config.ini key that will be used to indicate the default skin's name. + * this is ignored if there is a valid SKIN_PATH entry in the file. + */ +#define SKIN_NAME "skin.name" + /* default skin name */ #define SKIN_DEFAULT "HVGA" @@ -97,7 +102,7 @@ AvdInfo* android_avdInfo; * properties for the AVD. This will be used to launch the corresponding * core from the UI. */ -#define CORE_HARDWARE_INI "qemu-hardware.ini" +#define CORE_HARDWARE_INI "hardware-qemu.ini" /* certain disk image files are mounted read/write by the emulator * to ensure that several emulators referencing the same files @@ -139,8 +144,8 @@ struct AvdInfo { char* searchPaths[ MAX_SEARCH_PATHS ]; int numSearchPaths; char* contentPath; - IniFile* rootIni; /* root <foo>.ini file */ - IniFile* configIni; /* virtual device's config.ini */ + IniFile* rootIni; /* root <foo>.ini file, empty if missing */ + IniFile* configIni; /* virtual device's config.ini, NULL if missing */ IniFile* skinHardwareIni; /* skin-specific hardware.ini */ /* for both */ @@ -217,80 +222,99 @@ static const char* const _imageFileText[ AVD_IMAGE_MAX ] = { /*************************************************************** *************************************************************** ***** - ***** NORMAL VIRTUAL DEVICE SUPPORT + ***** UTILITY FUNCTIONS + ***** + ***** The following functions do not depend on the AvdInfo + ***** structure and could easily be moved elsewhere. ***** *****/ -/* compute path to the root SDK directory - * assume we are in $SDKROOT/tools/emulator[.exe] +/* Return the path to the Android SDK root installation. + * + * (*pFromEnv) will be set to 1 if it comes from the $ANDROID_SDK_ROOT + * environment variable, or 0 otherwise. + * + * Caller must free() returned string. */ -static int -_getSdkRoot( AvdInfo* i ) +static char* +_getSdkRoot( char *pFromEnv ) { const char* env; + char* sdkPath; char temp[PATH_MAX], *p=temp, *end=p+sizeof(temp); + /* If ANDROID_SDK_ROOT is defined is must point to a directory + * containing a valid SDK installation. + */ #define SDK_ROOT_ENV "ANDROID_SDK_ROOT" env = getenv(SDK_ROOT_ENV); if (env != NULL && env[0] != 0) { if (path_exists(env)) { D("found " SDK_ROOT_ENV ": %s", env); - i->sdkRootPath = ASTRDUP(env); - i->sdkRootPathFromEnv = 1; - return 0; + *pFromEnv = 1; + return ASTRDUP(env); } D(SDK_ROOT_ENV " points to unknown directory: %s", env); } - (void) bufprint_app_dir(temp, end); + *pFromEnv = 0; - i->sdkRootPath = path_parent(temp, 1); - if (i->sdkRootPath == NULL) { + /* We assume the emulator binary is under tools/ so use its + * parent as the Android SDK root. + */ + (void) bufprint_app_dir(temp, end); + sdkPath = path_parent(temp, 1); + if (sdkPath == NULL) { derror("can't find root of SDK directory"); - return -1; + return NULL; } - D("found SDK root at %s", i->sdkRootPath); - return 0; + D("found SDK root at %s", sdkPath); + return sdkPath; } -static void -_getSearchPaths( AvdInfo* i ) +/* Parse a given config.ini file and extract the list of SDK search paths + * from it. Returns the number of valid paths stored in 'searchPaths', or -1 + * in case of problem. + * + * Relative search paths in the config.ini will be stored as full pathnames + * relative to 'sdkRootPath'. + * + * 'searchPaths' must be an array of char* pointers of at most 'maxSearchPaths' + * entries. + */ +static int +_getSearchPaths( IniFile* configIni, + const char* sdkRootPath, + int maxSearchPaths, + char** searchPaths ) { char temp[PATH_MAX], *p = temp, *end= p+sizeof temp; int nn, count = 0; - - - for (nn = 0; nn < MAX_SEARCH_PATHS; nn++) { + for (nn = 0; nn < maxSearchPaths; nn++) { char* path; p = bufprint(temp, end, "%s%d", SEARCH_PREFIX, nn+1 ); if (p >= end) continue; - path = iniFile_getString( i->configIni, temp, NULL ); + path = iniFile_getString(configIni, temp, NULL); if (path != NULL) { DD(" found image search path: %s", path); if (!path_is_absolute(path)) { - p = bufprint(temp, end, "%s/%s", i->sdkRootPath, path); + p = bufprint(temp, end, "%s/%s", sdkRootPath, path); AFREE(path); path = ASTRDUP(temp); } - i->searchPaths[count++] = path; + searchPaths[count++] = path; } } - - i->numSearchPaths = count; - if (count == 0) { - derror("no search paths found in this AVD's configuration.\n" - "Weird, the AVD's config.ini file is malformed. Try re-creating it.\n"); - exit(2); - } - else - DD("found a total of %d search paths for this AVD", count); + return count; } +/* Check that an AVD name is valid. Returns 1 on success, 0 otherwise. + */ static int _checkAvdName( const char* name ) { @@ -301,37 +325,299 @@ _checkAvdName( const char* name ) return (len == len2); } -/* parse the root config .ini file. it is located in +/* Return the path to the AVD's root configuration .ini file. it is located in * ~/.android/avd/<name>.ini or Windows equivalent + * + * This file contains the path to the AVD's content directory, which + * includes its own config.ini. */ -static int -_getRootIni( AvdInfo* i ) +static char* +_getRootIniPath( const char* avdName ) { - char temp[PATH_MAX], *p=temp, *end=p+sizeof(temp); + char temp[PATH_MAX], *p=temp, *end=p+sizeof(temp); p = bufprint_config_path(temp, end); - p = bufprint(p, end, "/" ANDROID_AVD_DIR "/%s.ini", i->deviceName); + p = bufprint(p, end, "/" ANDROID_AVD_DIR "/%s.ini", avdName); + if (p >= end) { + return NULL; + } + if (!path_exists(temp)) { + return NULL; + } + return ASTRDUP(temp); +} + + +/* Retrieves a string corresponding to the target architecture + * when in the Android platform tree. The only way to do that + * properly for now is to look at $OUT/system/build.prop: + * + * ro.product.cpu-abi=<abi> + * + * Where <abi> can be 'armeabi', 'armeabi-v7a' or 'x86'. + */ +static const char* +_getBuildTargetArch( const char* androidOut ) +{ + const char* arch = "arm"; + char temp[PATH_MAX], *p=temp, *end=p+sizeof(temp); + FILE* file; + +#define ABI_PREFIX "ro.product.cpu.abi=" +#define ABI_PREFIX_LEN (sizeof(ABI_PREFIX)-1) + + p = bufprint(temp, end, "%s/system/build.prop", androidOut); if (p >= end) { - derror("device name too long"); + D("%s: ANDROID_PRODUCT_OUT too long: %s", __FUNCTION__, androidOut); + goto EXIT; + } + file = fopen(temp, "rb"); + if (file == NULL) { + D("Could not open file: %s: %s", temp, strerror(errno)); + D("Default target architecture=%s", arch); + goto EXIT; + } + + while (fgets(temp, sizeof temp, file) != NULL) { + /* Trim trailing newlines, if any */ + p = memchr(temp, '\0', sizeof temp); + if (p == NULL) + p = end; + if (p > temp && p[-1] == '\n') { + *--p = '\0'; + } + if (p > temp && p[-1] == '\r') { + *--p = '\0'; + } + /* force zero-termination in case of full-buffer */ + if (p == end) + *--p = '\0'; + + if (memcmp(temp, ABI_PREFIX, ABI_PREFIX_LEN) != 0) { + continue; + } + p = temp + ABI_PREFIX_LEN; + if (p >= end || !*p) + goto EXIT2; + + if (!strcmp("armeabi",p)) + arch = "arm"; + else if (!strcmp("armeabi-v7a",p)) + arch = "arm"; + else + arch = p; + + D("Found target ABI=%s, architecture=%s", p, arch); + goto EXIT2; + } + + D("Could not find target architecture, defaulting to %s", arch); +EXIT2: + fclose(file); +EXIT: + return arch; +} + +/* Returns the full path of a given file. + * + * If 'fileName' is an absolute path, this returns a simple copy. + * Otherwise, this returns a new string corresponding to <rootPath>/<fileName> + * + * This returns NULL if the paths are too long. + */ +static char* +_getFullFilePath( const char* rootPath, const char* fileName ) +{ + if (path_is_absolute(fileName)) { + return ASTRDUP(fileName); + } else { + char temp[PATH_MAX], *p=temp, *end=p+sizeof(temp); + + p = bufprint(temp, end, "%s/%s", rootPath, fileName); + if (p >= end) { + return NULL; + } + return ASTRDUP(temp); + } +} + +/* check that a given directory contains a valid skin. + * returns 1 on success, 0 on failure. + */ +static int +_checkSkinPath( const char* skinPath ) +{ + char temp[MAX_PATH], *p=temp, *end=p+sizeof(temp); + + /* for now, if it has a 'layout' file, it is a valid skin path */ + p = bufprint(temp, end, "%s/layout", skinPath); + if (p >= end || !path_exists(temp)) + return 0; + + return 1; +} + +/* Check that there is a skin named 'skinName' listed from 'skinDirRoot' + * this returns the full path of the skin directory (after alias expansions), + * including the skin name, or NULL on failure. + */ +static char* +_checkSkinSkinsDir( const char* skinDirRoot, + const char* skinName ) +{ + DirScanner* scanner; + char* result; + char temp[MAX_PATH], *p = temp, *end = p + sizeof(temp); + + p = bufprint(temp, end, "%s/skins/%s", skinDirRoot, skinName); + if (p >= end || !path_exists(temp)) { + DD(" ignore bad skin directory %s", temp); + return NULL; + } + + /* first, is this a normal skin directory ? */ + if (_checkSkinPath(temp)) { + /* yes */ + DD(" found skin directory: %s", temp); + return ASTRDUP(temp); + } + + /* second, is it an alias to another skin ? */ + *p = 0; + result = NULL; + scanner = dirScanner_new(temp); + if (scanner != NULL) { + for (;;) { + const char* file = dirScanner_next(scanner); + + if (file == NULL) + break; + + if (strncmp(file, "alias-", 6) || file[6] == 0) + continue; + + p = bufprint(temp, end, "%s/skins/%s", skinDirRoot, file+6); + if (p < end && _checkSkinPath(temp)) { + /* yes, it's an alias */ + DD(" skin alias '%s' points to skin directory: %s", + file+6, temp); + result = ASTRDUP(temp); + break; + } + } + dirScanner_free(scanner); + } + return result; +} + +/* try to see if the skin name leads to a magic skin or skin path directly + * returns 1 on success, 0 on error. + * + * on success, this sets up '*pSkinName' and '*pSkinDir' + */ +static int +_getSkinPathFromName( const char* skinName, + const char* sdkRootPath, + char** pSkinName, + char** pSkinDir ) +{ + char temp[PATH_MAX], *p=temp, *end=p+sizeof(temp); + + /* if the skin name has the format 'NNNNxNNN' where + * NNN is a decimal value, then this is a 'magic' skin + * name that doesn't require a skin directory + */ + if (isdigit(skinName[0])) { + int width, height; + if (sscanf(skinName, "%dx%d", &width, &height) == 2) { + D("'magic' skin format detected: %s", skinName); + *pSkinName = ASTRDUP(skinName); + *pSkinDir = NULL; + return 1; + } + } + + /* is the skin name a direct path to the skin directory ? */ + if (path_is_absolute(skinName) && _checkSkinPath(skinName)) { + goto FOUND_IT; + } + + /* is the skin name a relative path from the SDK root ? */ + p = bufprint(temp, end, "%s/%s", sdkRootPath, skinName); + if (p < end && _checkSkinPath(temp)) { + skinName = temp; + goto FOUND_IT; + } + + /* nope */ + return 0; + +FOUND_IT: + if (path_split(skinName, pSkinDir, pSkinName) < 0) { + derror("malformed skin name: %s", skinName); + exit(2); + } + D("found skin '%s' in directory: %s", *pSkinName, *pSkinDir); + return 1; +} + +/*************************************************************** + *************************************************************** + ***** + ***** NORMAL VIRTUAL DEVICE SUPPORT + ***** + *****/ + +/* compute path to the root SDK directory + * assume we are in $SDKROOT/tools/emulator[.exe] + */ +static int +_avdInfo_getSdkRoot( AvdInfo* i ) +{ + + i->sdkRootPath = _getSdkRoot(&i->sdkRootPathFromEnv); + if (i->sdkRootPath == NULL) + return -1; + + return 0; +} + +/* parse the root config .ini file. it is located in + * ~/.android/avd/<name>.ini or Windows equivalent + */ +static int +_avdInfo_getRootIni( AvdInfo* i ) +{ + char* iniPath = _getRootIniPath( i->deviceName ); + + if (iniPath == NULL) { + derror("unknown virtual device name: '%s'", i->deviceName); return -1; } - i->rootIni = iniFile_newFromFile(temp); + D("Android virtual device file at: %s", iniPath); + + i->rootIni = iniFile_newFromFile(iniPath); + AFREE(iniPath); + if (i->rootIni == NULL) { - derror("unknown virtual device name: '%s'", i->deviceName); + derror("Corrupt virtual device config file!"); return -1; } - D("root virtual device file at %s", temp); return 0; } -/* the .ini variable name that points to the content directory - * in a root AVD ini file. This is required */ -# define ROOT_PATH_KEY "path" - +/* Returns the AVD's content path, i.e. the directory that contains + * the AVD's content files (e.g. data partition, cache, sd card, etc...). + * + * We extract this by parsing the root config .ini file, looking for + * a "path" elements. + */ static int -_getContentPath( AvdInfo* i ) +_avdInfo_getContentPath( AvdInfo* i ) { +# define ROOT_PATH_KEY "path" + i->contentPath = iniFile_getString(i->rootIni, ROOT_PATH_KEY, NULL); if (i->contentPath == NULL) { @@ -343,36 +629,157 @@ _getContentPath( AvdInfo* i ) return 0; } -/* find and parse the config.ini file from the content directory */ -static int -_getConfigIni(AvdInfo* i) +/* Look for a named file inside the AVD's content directory. + * Returns NULL if it doesn't exist, or a strdup() copy otherwise. + */ +static char* +_avdInfo_getContentFilePath(AvdInfo* i, const char* fileName) { - char temp[PATH_MAX], *p=temp, *end=p+sizeof(temp); + char temp[MAX_PATH], *p = temp, *end = p + sizeof(temp); - p = bufprint(p, end, "%s/config.ini", i->contentPath); + p = bufprint(p, end, "%s/%s", i->contentPath, fileName); if (p >= end) { derror("can't access virtual device content directory"); - return -1; + return NULL; } - -#if 1 /* XXX: TODO: remove this in the future */ - /* for now, allow a non-existing config.ini */ if (!path_exists(temp)) { + return NULL; + } + return ASTRDUP(temp); +} + +/* find and parse the config.ini file from the content directory */ +static int +_avdInfo_getConfigIni(AvdInfo* i) +{ + char* iniPath = _avdInfo_getContentFilePath(i, "config.ini"); + + /* Allow non-existing config.ini */ + if (iniPath == NULL) { D("virtual device has no config file - no problem"); return 0; } -#endif - i->configIni = iniFile_newFromFile(temp); + D("virtual device config file: %s", iniPath); + i->configIni = iniFile_newFromFile(iniPath); + AFREE(iniPath); + if (i->configIni == NULL) { derror("bad config: %s", - "virtual device directory lacks config.ini"); + "virtual device has corrupted config.ini"); + return -1; + } + return 0; +} + +/* The AVD's config.ini contains a list of search paths (all beginning + * with SEARCH_PREFIX) which are directory locations searched for + * AVD platform files. + */ +static void +_avdInfo_getSearchPaths( AvdInfo* i ) +{ + if (i->configIni == NULL) + return; + + i->numSearchPaths = _getSearchPaths( i->configIni, + i->sdkRootPath, + MAX_SEARCH_PATHS, + i->searchPaths ); + if (i->numSearchPaths == 0) { + derror("no search paths found in this AVD's configuration.\n" + "Weird, the AVD's config.ini file is malformed. Try re-creating it.\n"); + exit(2); + } + else + DD("found a total of %d search paths for this AVD", i->numSearchPaths); +} + +/* Search a file in the SDK search directories. Return NULL if not found, + * or a strdup() otherwise. + */ +static char* +_avdInfo_getSdkFilePath(AvdInfo* i, const char* fileName) +{ + char temp[MAX_PATH], *p = temp, *end = p + sizeof(temp); + + do { + /* try the search paths */ + int nn; + + for (nn = 0; nn < i->numSearchPaths; nn++) { + const char* searchDir = i->searchPaths[nn]; + + p = bufprint(temp, end, "%s/%s", searchDir, fileName); + if (p < end && path_exists(temp)) { + DD("found %s in search dir: %s", fileName, searchDir); + goto FOUND; + } + DD(" no %s in search dir: %s", fileName, searchDir); + } + + return NULL; + + } while (0); + +FOUND: + return ASTRDUP(temp); +} + +/* Search for a file in the content directory, and if not found, in the + * SDK search directory. Returns NULL if not found. + */ +static char* +_avdInfo_getContentOrSdkFilePath(AvdInfo* i, const char* fileName) +{ + char* path; + + path = _avdInfo_getContentFilePath(i, fileName); + if (path) + return path; + + path = _avdInfo_getSdkFilePath(i, fileName); + if (path) + return path; + + return NULL; +} + +#if 0 +static int +_avdInfo_findContentOrSdkImage(AvdInfo* i, AvdImageType id) +{ + const char* fileName = _imageFileNames[id]; + char* path = _avdInfo_getContentOrSdkFilePath(i, fileName); + + i->imagePath[id] = path; + i->imageState[id] = IMAGE_STATE_READONLY; + + if (path == NULL) + return -1; + else + return 0; +} +#endif + +/* Returns path to the core hardware .ini file. This contains the + * hardware configuration that is read by the core. The content of this + * file is auto-generated before launching a core, but we need to know + * its path before that. + */ +static int +_avdInfo_getCoreHwIniPath( AvdInfo* i, const char* basePath ) +{ + i->coreHardwareIniPath = _getFullFilePath(basePath, CORE_HARDWARE_INI); + if (i->coreHardwareIniPath == NULL) { + DD("Path too long for %s: %s", CORE_HARDWARE_INI, basePath); return -1; } - D("virtual device config file: %s", temp); + D("using core hw config path: %s", i->coreHardwareIniPath); return 0; } + /*************************************************************** *************************************************************** ***** @@ -720,7 +1127,7 @@ imageLoader_loadOptional( ImageLoader *l, AvdImageType img_type, * and lock the files that need it. */ static int -_getImagePaths(AvdInfo* i, AvdInfoParams* params ) +_avdInfo_getImagePaths(AvdInfo* i, AvdInfoParams* params ) { int wipeData = (params->flags & AVDINFO_WIPE_DATA) != 0; int wipeCache = (params->flags & AVDINFO_WIPE_CACHE) != 0; @@ -826,260 +1233,12 @@ _getImagePaths(AvdInfo* i, AvdInfoParams* params ) return 0; } -/* check that a given directory contains a valid skin. - * returns 1 on success, 0 on failure. - */ -static int -_checkSkinPath( const char* skinPath ) -{ - char temp[MAX_PATH], *p=temp, *end=p+sizeof(temp); - - /* for now, if it has a 'layout' file, it is a valid skin path */ - p = bufprint(temp, end, "%s/layout", skinPath); - if (p >= end || !path_exists(temp)) - return 0; - - return 1; -} - -/* check that there is a skin named 'skinName' listed from 'skinDirRoot' - * this returns 1 on success, 0 on failure - * on success, the 'temp' buffer will get the path containing the real - * skin directory (after alias expansion), including the skin name. - */ -static int -_checkSkinDir( char* temp, - char* end, - const char* skinDirRoot, - const char* skinName ) -{ - DirScanner* scanner; - char *p; - int result; - - p = bufprint(temp, end, "%s/skins/%s", - skinDirRoot, skinName); - - if (p >= end || !path_exists(temp)) { - DD(" ignore bad skin directory %s", temp); - return 0; - } - - /* first, is this a normal skin directory ? */ - if (_checkSkinPath(temp)) { - /* yes */ - DD(" found skin directory: %s", temp); - return 1; - } - - /* second, is it an alias to another skin ? */ - *p = 0; - result = 0; - scanner = dirScanner_new(temp); - if (scanner != NULL) { - for (;;) { - const char* file = dirScanner_next(scanner); - - if (file == NULL) - break; - - if (strncmp(file, "alias-", 6) || file[6] == 0) - continue; - - p = bufprint(temp, end, "%s/skins/%s", - skinDirRoot, file+6); - - if (p < end && _checkSkinPath(temp)) { - /* yes, it's an alias */ - DD(" skin alias '%s' points to skin directory: %s", - file+6, temp); - result = 1; - break; - } - } - dirScanner_free(scanner); - } - return result; -} - -/* try to see if the skin name leads to a magic skin or skin path directly - * returns 1 on success, 0 on error. - * on success, this sets up 'skinDirPath' and 'skinName' in the AvdInfo. - */ -static int -_getSkinPathFromName( AvdInfo* i, const char* skinName ) -{ - char temp[PATH_MAX], *p=temp, *end=p+sizeof(temp); - - /* if the skin name has the format 'NNNNxNNN' where - * NNN is a decimal value, then this is a 'magic' skin - * name that doesn't require a skin directory - */ - if (isdigit(skinName[0])) { - int width, height; - if (sscanf(skinName, "%dx%d", &width, &height) == 2) { - D("'magic' skin format detected: %s", skinName); - i->skinName = ASTRDUP(skinName); - i->skinDirPath = NULL; - return 1; - } - } - - /* is the skin name a direct path to the skin directory ? */ - if (_checkSkinPath(skinName)) { - goto FOUND_IT; - } - - /* is the skin name a relative path from the SDK root ? */ - p = bufprint(temp, end, "%s/%s", i->sdkRootPath, skinName); - if (p < end && _checkSkinPath(temp)) { - skinName = temp; - goto FOUND_IT; - } - - /* nope */ - return 0; - -FOUND_IT: - if (path_split(skinName, &i->skinDirPath, &i->skinName) < 0) { - derror("malformed skin name: %s", skinName); - exit(2); - } - D("found skin '%s' in directory: %s", i->skinName, i->skinDirPath); - return 1; -} - -/* return 0 on success, -1 on error */ -static int -_getSkin( AvdInfo* i, AvdInfoParams* params ) -{ - char* skinName; - char temp[PATH_MAX], *p=temp, *end=p+sizeof(temp); - char explicitSkin = 1; - - /* this function is used to compute the 'skinName' and 'skinDirPath' - * fields of the AvdInfo. - */ - - /* processing here is a bit tricky, so here's how it happens - * - * - command-line option '-skin <name>' can be used to specify the - * name of a skin, to override the AVD settings. - * - * - skins are searched from <dir>/../skins for each <dir> in the - * images search list, unless a '-skindir <path>' option has been - * provided on the command-line - * - * - otherwise, the config.ini can also contain a SKIN_PATH key that - * shall give the full path to the skin directory, either relative - * to the SDK root, or an absolute path. - * - * - skin names like '320x480' corresponds to "magic skins" that - * simply display a framebuffer, without any ornaments of the - * corresponding size. They do not correspond to any real skin - * directory / files and are handled later. But they must be - * recognized here and report a NULL skindir. - */ - if (params->skinName) { - skinName = ASTRDUP(params->skinName); - } else { - skinName = iniFile_getString( i->configIni, SKIN_PATH, NULL ); - explicitSkin = 0; - } - - /* first, check that the skin name is not magic or a direct - * directory path - */ - if (skinName != NULL && _getSkinPathFromName(i, skinName)) { - AFREE(skinName); - return 0; - } - - /* if not, the default skinName is "HVGA" */ - if (skinName == NULL) { - skinName = ASTRDUP(SKIN_DEFAULT); - explicitSkin = 0; - } - - i->skinName = skinName; - - /* now try to find the skin directory for that name - - * first try the content directory */ - do { - /* if there is a single 'skin' directory in - * the content directory, assume that's what the - * user wants, unless an explicit name was given - */ - if (!explicitSkin) { - p = bufprint(temp, end, "%s/skin", i->contentPath); - if (p < end && _checkSkinPath(temp)) { - D("using skin content from %s", temp); - AFREE(i->skinName); - i->skinName = ASTRDUP("skin"); - i->skinDirPath = ASTRDUP(i->contentPath); - return 0; - } - } - - /* look in content directory */ - if (_checkSkinDir(temp, end, i->contentPath, skinName)) - break; - - /* look in the search paths. For each <dir> in the list, - * look the skins in <dir>/.. */ - { - int nn; - for (nn = 0; nn < i->numSearchPaths; nn++) { - char* parentDir = path_parent(i->searchPaths[nn], 1); - int ret; - if (parentDir == NULL) - continue; - ret=_checkSkinDir(temp, end, parentDir, skinName); - AFREE(parentDir); - if (ret) - break; - } - if (nn < i->numSearchPaths) - break; - } - - /* didn't find it */ - if (explicitSkin) { - derror("could not find directory for skin '%s'," - " please use a different name", skinName); - exit(2); - } else { - dwarning("no skin directory matched '%s', so reverted to default", - skinName); - AFREE(i->skinName); - params->skinName = SKIN_DEFAULT; - return _getSkin(i, params); - } - - return -1; - - } while (0); - - /* separate skin name from parent directory. the skin name - * returned in 'temp' might be different from the original - * one due to alias expansion so strip it. - */ - AFREE(i->skinName); - - if (path_split(temp, &i->skinDirPath, &i->skinName) < 0) { - derror("weird skin path: %s", temp); - return -1; - } - DD("found skin '%s' in directory: %s", i->skinName, i->skinDirPath); - return 0; -} - /* If the user didn't explicitely provide an SD Card path, * check the SDCARD_PATH key in config.ini and use that if * available. */ static void -_getSDCardPath( AvdInfo* i, AvdInfoParams* params ) +_avdInfo_getSDCardPath( AvdInfo* i, AvdInfoParams* params ) { const char* path; @@ -1093,22 +1252,6 @@ _getSDCardPath( AvdInfo* i, AvdInfoParams* params ) params->forcePaths[AVD_IMAGE_SDCARD] = path; } -static int -_getCoreHwIniPath( AvdInfo* i, const char* basePath ) -{ - char temp[PATH_MAX], *p=temp, *end=p+sizeof(temp); - - p = bufprint(temp, end, "%s/%s", basePath, CORE_HARDWARE_INI); - if (p >= end) { - DD("Path too long for %s:", CORE_HARDWARE_INI, basePath); - return -1; - } - - D("using core hw config path: %s", temp); - i->coreHardwareIniPath = ASTRDUP(temp); - return 0; -} - AvdInfo* avdInfo_new( const char* name, AvdInfoParams* params ) { @@ -1125,25 +1268,24 @@ avdInfo_new( const char* name, AvdInfoParams* params ) ANEW0(i); i->deviceName = ASTRDUP(name); - if ( _getSdkRoot(i) < 0 || - _getRootIni(i) < 0 || - _getContentPath(i) < 0 || - _getConfigIni(i) < 0 || - _getCoreHwIniPath(i, i->contentPath) < 0 ) + if ( _avdInfo_getSdkRoot(i) < 0 || + _avdInfo_getRootIni(i) < 0 || + _avdInfo_getContentPath(i) < 0 || + _avdInfo_getConfigIni(i) < 0 || + _avdInfo_getCoreHwIniPath(i, i->contentPath) < 0 ) goto FAIL; /* look for image search paths. handle post 1.1/pre cupcake * obsolete SDKs. */ - _getSearchPaths(i); - _getSDCardPath(i, params); + _avdInfo_getSearchPaths(i); + _avdInfo_getSDCardPath(i, params); /* don't need this anymore */ iniFile_free(i->rootIni); i->rootIni = NULL; - if ( _getImagePaths(i, params) < 0 || - _getSkin (i, params) < 0 ) + if ( _avdInfo_getImagePaths(i, params) < 0 ) goto FAIL; return i; @@ -1177,17 +1319,8 @@ FAIL: ***** the content directory, no SDK images search path. *****/ -/* used to fake a config.ini located in the content directory */ static int -_getBuildConfigIni( AvdInfo* i ) -{ - /* a blank file is ok at the moment */ - i->configIni = iniFile_newFromMemory( "", 0 ); - return 0; -} - -static int -_getBuildImagePaths( AvdInfo* i, AvdInfoParams* params ) +_avdInfo_getBuildImagePaths( AvdInfo* i, AvdInfoParams* params ) { int wipeData = (params->flags & AVDINFO_WIPE_DATA) != 0; int noCache = (params->flags & AVDINFO_NO_CACHE) != 0; @@ -1316,85 +1449,21 @@ _getBuildImagePaths( AvdInfo* i, AvdInfoParams* params ) return 0; } -static int -_getBuildSkin( AvdInfo* i, AvdInfoParams* params ) -{ - /* the (current) default skin name for our build system */ - const char* skinName = params->skinName; - const char* skinDir = params->skinRootPath; - char temp[PATH_MAX], *p=temp, *end=p+sizeof(temp); - char* q; - - if (!skinName) { - /* the (current) default skin name for the build system */ - skinName = SKIN_DEFAULT; - D("selecting default skin name '%s'", skinName); - } - - if (!skinDir) { - -#define PREBUILT_SKINS_DIR "development/tools/emulator/skins" -#define PRODUCT_SKIN_DIR "skin" - - do { - /* look for the product skin in $ANDROID_PRODUCT_OUT/skin if no skin name is defined */ - if (!params->skinName) { - /* look for <product_out>/skin first */ - p = bufprint( temp, end, "%s/skin", - i->androidOut ); - if (path_exists(temp)) { - p = bufprint( temp, end, "%s", - i->androidOut ); - skinName = PRODUCT_SKIN_DIR; - D("selecting default product skin at '%s/%s'", temp, skinName); - break; - } - } - - /* next try in <sysdir>/../skins */ - p = bufprint( temp, end, "%s/../skins", - i->androidBuildRoot ); - if (path_exists(temp)) - break; - - /* the (current) default skin directory */ - p = bufprint( temp, end, "%s/%s", - i->androidBuildRoot, PREBUILT_SKINS_DIR ); - } while (0); - - } else { - p = bufprint( temp, end, "%s", skinDir ); - } - - i->skinName = ASTRDUP(skinName); - - q = bufprint(p, end, "/%s/layout", skinName); - if (q >= end || !path_exists(temp)) { - DD("skin content directory does not exist: %s", temp); - if (skinDir) - dwarning("could not find valid skin '%s' in %s:\n", - skinName, temp); - return -1; - } - *p = 0; - DD("found skin path: %s", temp); - i->skinDirPath = ASTRDUP(temp); - - return 0; -} - /* Read a hardware.ini if it is located in the skin directory */ static int -_getBuildSkinHardwareIni( AvdInfo* i ) +_avdInfo_getBuildSkinHardwareIni( AvdInfo* i ) { + char* skinName; + char* skinDirPath; char temp[PATH_MAX], *p=temp, *end=p+sizeof(temp); - if (i->skinDirPath == NULL || i->skinName == NULL) + avdInfo_getSkinInfo(i, &skinName, &skinDirPath); + if (skinDirPath == NULL) return 0; - p = bufprint(temp, end, "%s/%s/hardware.ini", i->skinDirPath, i->skinName); + p = bufprint(temp, end, "%s/%s/hardware.ini", skinDirPath, skinName); if (p >= end || !path_exists(temp)) { - DD("no skin-specific hardware.ini in %s", i->skinDirPath); + DD("no skin-specific hardware.ini in %s", skinDirPath); return 0; } @@ -1406,76 +1475,6 @@ _getBuildSkinHardwareIni( AvdInfo* i ) return 0; } -#define ABI_PREFIX "ro.product.cpu.abi=" -#define ABI_PREFIX_LEN (sizeof(ABI_PREFIX)-1) - -/* Retrieves a string corresponding to the target architecture - * when in the Android platform tree. The only way to do that - * properly for now is to look at $OUT/system/build.prop: - * - * ro.product.cpu-abi=<abi> - * - * Where <abi> can be 'armeabi', 'armeabi-v7a' or 'x86'. - */ -static const char* -_getBuildTargetArch( AvdInfo* i ) -{ - const char* arch = "arm"; - char temp[PATH_MAX], *p=temp, *end=p+sizeof(temp); - FILE* file; - - p = bufprint(temp, end, "%s/system/build.prop", i->androidOut); - if (p >= end) { - D("%s: ANDROID_PRODUCT_OUT too long: %s", __FUNCTION__, i->androidOut); - goto EXIT; - } - file = fopen(temp, "rb"); - if (file == NULL) { - D("Could not open file: %s: %s", temp, strerror(errno)); - D("Default target architecture=%s", arch); - goto EXIT; - } - - while (fgets(temp, sizeof temp, file) != NULL) { - /* Trim trailing newlines, if any */ - p = memchr(temp, '\0', sizeof temp); - if (p == NULL) - p = end; - if (p > temp && p[-1] == '\n') { - *--p = '\0'; - } - if (p > temp && p[-1] == '\r') { - *--p = '\0'; - } - /* force zero-termination in case of full-buffer */ - if (p == end) - *--p = '\0'; - - if (memcmp(temp, ABI_PREFIX, ABI_PREFIX_LEN) != 0) { - continue; - } - p = temp + ABI_PREFIX_LEN; - if (p >= end || !*p) - goto EXIT2; - - if (!strcmp("armeabi",p)) - arch = "arm"; - else if (!strcmp("armeabi-v7a",p)) - arch = "arm"; - else - arch = p; - - D("Found target ABI=%s, architecture=%s", p, arch); - goto EXIT2; - } - - D("Could not find target architecture, defaulting to %s", arch); -EXIT2: - fclose(file); -EXIT: - return arch; -} - AvdInfo* avdInfo_newForAndroidBuild( const char* androidBuildRoot, const char* androidOut, @@ -1489,19 +1488,20 @@ avdInfo_newForAndroidBuild( const char* androidBuildRoot, i->androidBuildRoot = ASTRDUP(androidBuildRoot); i->androidOut = ASTRDUP(androidOut); i->contentPath = ASTRDUP(androidOut); - i->targetArch = ASTRDUP(_getBuildTargetArch(i)); + i->targetArch = ASTRDUP(_getBuildTargetArch(i->androidOut)); /* TODO: find a way to provide better information from the build files */ i->deviceName = ASTRDUP("<build>"); - if (_getBuildConfigIni(i) < 0 || - _getBuildImagePaths(i, params) < 0 || - _getCoreHwIniPath(i, i->androidOut) < 0 ) + /* There is no config.ini in the build */ + i->configIni = NULL; + + if (_avdInfo_getBuildImagePaths(i, params) < 0 || + _avdInfo_getCoreHwIniPath(i, i->androidOut) < 0 ) goto FAIL; - /* we don't need to fail if there is no valid skin */ - _getBuildSkin(i, params); - _getBuildSkinHardwareIni(i); + /* Read the build skin's hardware.ini, if any */ + _avdInfo_getBuildSkinHardwareIni(i); return i; @@ -1549,18 +1549,6 @@ avdInfo_isImageReadOnly( AvdInfo* i, AvdImageType imageType ) return (i->imageState[imageType] == IMAGE_STATE_READONLY); } -const char* -avdInfo_getSkinName( AvdInfo* i ) -{ - return i->skinName; -} - -const char* -avdInfo_getSkinDir ( AvdInfo* i ) -{ - return i->skinDirPath; -} - int avdInfo_getHwConfig( AvdInfo* i, AndroidHwConfig* hw ) { @@ -1628,3 +1616,107 @@ avdInfo_getCoreHwIniPath( AvdInfo* i ) { return i->coreHardwareIniPath; } + + +void +avdInfo_getSkinInfo( AvdInfo* i, char** pSkinName, char** pSkinDir ) +{ + char* skinName = NULL; + char* skinPath; + char temp[PATH_MAX], *p=temp, *end=p+sizeof(temp); + + *pSkinName = NULL; + *pSkinDir = NULL; + + /* First, see if the config.ini contains a SKIN_PATH entry that + * names the full directory path for the skin. + */ + if ( i->configIni != NULL ) { + skinPath = iniFile_getString( i->configIni, SKIN_PATH, NULL ); + if (skinPath != NULL) { + /* If this skin name is magic or a direct directory path + * we have our result right here. + */ + if (_getSkinPathFromName(skinPath, i->sdkRootPath, + pSkinName, pSkinDir )) { + AFREE(skinPath); + return; + } + } + + /* The SKIN_PATH entry was not valid, so look at SKIN_NAME */ + D("Warning: config.ini contains invalid %s entry: %s", SKIN_PATH, skinPath); + AFREE(skinPath); + + skinName = iniFile_getString( i->configIni, SKIN_NAME, NULL ); + } + + if (skinName == NULL) { + /* If there is no skin listed in the config.ini, try to see if + * there is one single 'skin' directory in the content directory. + */ + p = bufprint(temp, end, "%s/skin", i->contentPath); + if (p < end && _checkSkinPath(temp)) { + D("using skin content from %s", temp); + AFREE(i->skinName); + *pSkinName = ASTRDUP("skin"); + *pSkinDir = ASTRDUP(i->contentPath); + return; + } + + /* otherwise, use the default name */ + skinName = ASTRDUP(SKIN_DEFAULT); + } + + /* now try to find the skin directory for that name - + */ + do { + /* first try the content directory, i.e. $CONTENT/skins/<name> */ + skinPath = _checkSkinSkinsDir(i->contentPath, skinName); + if (skinPath != NULL) + break; + +#define PREBUILT_SKINS_ROOT "development/tools/emulator" + + /* if we are in the Android build, try the prebuilt directory */ + if (i->inAndroidBuild) { + p = bufprint( temp, end, "%s/%s", + i->androidBuildRoot, PREBUILT_SKINS_ROOT ); + if (p < end) { + skinPath = _checkSkinSkinsDir(temp, skinName); + if (skinPath != NULL) + break; + } + } + + /* look in the search paths. For each <dir> in the list, + * look into <dir>/../skins/<name>/ */ + { + int nn; + for (nn = 0; nn < i->numSearchPaths; nn++) { + char* parentDir = path_parent(i->searchPaths[nn], 1); + if (parentDir == NULL) + continue; + skinPath = _checkSkinSkinsDir(parentDir, skinName); + AFREE(parentDir); + if (skinPath != NULL) + break; + } + if (nn < i->numSearchPaths) + break; + } + + /* We didn't find anything ! */ + return; + + } while (0); + + if (path_split(skinPath, pSkinDir, pSkinName) < 0) { + derror("weird skin path: %s", skinPath); + AFREE(skinPath); + return; + } + DD("found skin '%s' in directory: %s", *pSkinName, *pSkinDir); + AFREE(skinPath); + return; +} diff --git a/android/avd/info.h b/android/avd/info.h index 2a85964..adcabfd 100644 --- a/android/avd/info.h +++ b/android/avd/info.h @@ -130,6 +130,17 @@ void avdInfo_free( AvdInfo* i ); */ const char* avdInfo_getName( AvdInfo* i ); +/* Returns the path to a given AVD image file. This will return NULL if + * the file cannot be found / does not exist. + */ +const char* avdInfo_getImagePath( AvdInfo* i, AvdImageType imageType ); + +/* Returns the default path of a given AVD image file. This only makes sense + * if avdInfo_getImagePath() returned NULL. + */ +const char* avdInfo_getImageDefaultPath( AvdInfo* i, AvdImageType imageType ); + + /* Try to find the path of a given image file, returns NULL * if the corresponding file could not be found. the string * belongs to the AvdInfo object. @@ -154,19 +165,18 @@ int avdInfo_lockImageFile( AvdInfo* i, AvdImageType imageType, int a /* Manually set the path of a given image file. */ void avdInfo_setImageFile( AvdInfo* i, AvdImageType imageType, const char* imagePath ); -/* Returns the path of the skin directory */ -/* the string belongs to the AvdInfo object */ -const char* avdInfo_getSkinPath( AvdInfo* i ); - -/* Returns the name of the virtual device's skin */ -const char* avdInfo_getSkinName( AvdInfo* i ); - -/* Returns the root skin directory for this device */ -const char* avdInfo_getSkinDir ( AvdInfo* i ); - /* Returns the content path of the virtual device */ const char* avdInfo_getContentPath( AvdInfo* i ); +/* Retrieve the AVD's specific skin information. + * On exit: + * '*pSkinName' points to the skin's name. + * '*pSkinDir' points to the skin's directory. + * + * Note that the skin's content will be under <skinDir>/<skinName>. + */ +void avdInfo_getSkinInfo( AvdInfo* i, char** pSkinName, char** pSkinDir ); + /* Returns TRUE iff in the Android build system */ int avdInfo_inAndroidBuild( AvdInfo* i ); diff --git a/android/main-common.c b/android/main-common.c index 05108a1..3bca6c4 100644 --- a/android/main-common.c +++ b/android/main-common.c @@ -710,26 +710,9 @@ _forceAvdImagePath( AvdImageType imageType, android_avdParams->forcePaths[imageType] = path; } -AvdInfo* createAVD(AndroidOptions* opts, int* inAndroidBuild) -{ - AvdInfo* ret = NULL; - char tmp[MAX_PATH]; - char* tmpend = tmp + sizeof(tmp); - char* android_build_root = NULL; - char* android_build_out = NULL; - - /* setup the virtual device parameters from our options - */ - if (opts->no_cache) { - android_avdParams->flags |= AVDINFO_NO_CACHE; - } - if (opts->wipe_data) { - android_avdParams->flags |= AVDINFO_WIPE_DATA | AVDINFO_WIPE_CACHE; - } - if (opts->no_snapstorage) { - android_avdParams->flags |= AVDINFO_NO_SNAPSHOTS; - } +void sanitizeOptions( AndroidOptions* opts ) +{ /* legacy support: we used to use -system <dir> and -image <file> * instead of -sysdir <dir> and -system <file>, so handle this by checking * whether the options point to directories or files. @@ -762,6 +745,72 @@ AvdInfo* createAVD(AndroidOptions* opts, int* inAndroidBuild) opts->system = NULL; } + if (opts->nojni) { + opts->no_jni = opts->nojni; + opts->nojni = 0; + } + + if (opts->nocache) { + opts->no_cache = opts->nocache; + opts->nocache = 0; + } + + if (opts->noaudio) { + opts->no_audio = opts->noaudio; + opts->noaudio = 0; + } + + if (opts->noskin) { + opts->no_skin = opts->noskin; + opts->noskin = 0; + } + + /* If -no-cache is used, ignore any -cache argument */ + if (opts->no_cache) { + opts->cache = 0; + } + + /* the purpose of -no-audio is to disable sound output from the emulator, + * not to disable Audio emulation. So simply force the 'none' backends */ + if (opts->no_audio) + opts->audio = "none"; + + /* we don't accept -skindir without -skin now + * to simplify the autoconfig stuff with virtual devices + */ + if (opts->no_skin) { + opts->skin = "320x480"; + opts->skindir = NULL; + } + + if (opts->skindir) { + if (!opts->skin) { + derror( "the -skindir <path> option requires a -skin <name> option"); + exit(1); + } + } +} + +AvdInfo* createAVD(AndroidOptions* opts, int* inAndroidBuild) +{ + AvdInfo* ret = NULL; + char tmp[MAX_PATH]; + char* tmpend = tmp + sizeof(tmp); + char* android_build_root = NULL; + char* android_build_out = NULL; + + /* setup the virtual device parameters from our options + */ + if (opts->no_cache) { + android_avdParams->flags |= AVDINFO_NO_CACHE; + } + if (opts->wipe_data) { + android_avdParams->flags |= AVDINFO_WIPE_DATA | AVDINFO_WIPE_CACHE; + } + if (opts->no_snapstorage) { + android_avdParams->flags |= AVDINFO_NO_SNAPSHOTS; + } + /* If no AVD name was given, try to find the top of the * Android build tree */ @@ -884,20 +933,6 @@ AvdInfo* createAVD(AndroidOptions* opts, int* inAndroidBuild) _forceAvdImagePath(AVD_IMAGE_SDCARD, opts->sdcard, "SD Card", 0); _forceAvdImagePath(AVD_IMAGE_SNAPSHOTS, opts->snapstorage, "snapshots", 0); - /* we don't accept -skindir without -skin now - * to simplify the autoconfig stuff with virtual devices - */ - if (opts->no_skin) { - opts->skin = "320x480"; - opts->skindir = NULL; - } - - if (opts->skindir) { - if (!opts->skin) { - derror( "the -skindir <path> option requires a -skin <name> option"); - exit(1); - } - } android_avdParams->skinName = opts->skin; android_avdParams->skinRootPath = opts->skindir; diff --git a/android/main-common.h b/android/main-common.h index a74bf52..0d184d5 100644 --- a/android/main-common.h +++ b/android/main-common.h @@ -60,6 +60,12 @@ void init_sdl_ui(AConfig* skinConfig, const char* skinPath, AndroidOptions* opts); +/* Sanitize options. This deals with a few legacy options that are now + * handled differently. Call before anything else that needs to read + * the options list. + */ +void sanitizeOptions( AndroidOptions* opts ); + /* Creates and initializes AvdInfo instance for the given options. * Param: * opts - Options passed to the main() @@ -70,6 +76,12 @@ void init_sdl_ui(AConfig* skinConfig, */ struct AvdInfo* createAVD(AndroidOptions* opts, int* inAndroidBuild); +/* Populate the hwConfig fields corresponding to the kernel/disk images + * used by the emulator. This will zero *hwConfig first. + */ +void findImagePaths( AndroidHwConfig* hwConfig, + AndroidOptions* opts ); + /* Updates hardware configuration for the given AVD and options. * Param: * hwConfig - Hardware configuration to update. diff --git a/android/main.c b/android/main.c index b99097f..ddf8463 100644 --- a/android/main.c +++ b/android/main.c @@ -214,6 +214,8 @@ int main(int argc, char **argv) exit(0); } + sanitizeOptions(opts); + /* Initialization of UI started with -attach-core should work differently * than initialization of UI that starts the core. In particular.... */ @@ -224,29 +226,30 @@ int main(int argc, char **argv) exit(1); } - if (opts->nojni) - opts->no_jni = opts->nojni; - - if (opts->nocache) - opts->no_cache = opts->nocache; - - if (opts->noaudio) - opts->no_audio = opts->noaudio; - - if (opts->noskin) - opts->no_skin = opts->noskin; - /* Parses options and builds an appropriate AVD. */ avd = android_avdInfo = createAVD(opts, &inAndroidBuild); /* get the skin from the virtual device configuration */ - opts->skin = (char*) avdInfo_getSkinName( avd ); - opts->skindir = (char*) avdInfo_getSkinDir( avd ); + if (opts->skindir != NULL) { + if (opts->skin == NULL) { + /* NOTE: Normally handled by sanitizeOptions(), just be safe */ + derror("The -skindir <path> option requires a -skin <name> option"); + exit(2); + } + } else { + char* skinName; + char* skinDir; - if (opts->skin) { - D("autoconfig: -skin %s", opts->skin); - } - if (opts->skindir) { + avdInfo_getSkinInfo(avd, &skinName, &skinDir); + + if (opts->skin == NULL) { + opts->skin = skinName; + D("autoconfig: -skin %s", opts->skin); + } else { + AFREE(skinName); + } + + opts->skindir = skinDir; D("autoconfig: -skindir %s", opts->skindir); } @@ -328,9 +331,6 @@ int main(int argc, char **argv) opts->trace = tracePath; } - if (opts->no_cache) - opts->cache = 0; - n = 1; /* generate arguments for the underlying qemu main() */ { @@ -393,11 +393,6 @@ int main(int argc, char **argv) args[n++] = "-netfast"; } - /* the purpose of -no-audio is to disable sound output from the emulator, - * not to disable Audio emulation. So simply force the 'none' backends */ - if (opts->no_audio) - opts->audio = "none"; - if (opts->audio) { args[n++] = "-audio"; args[n++] = opts->audio; |