int SSkirmishAISpecifier_hash( const struct SSkirmishAISpecifier* const spec ) { const bool useShortName = (spec->shortName != NULL); const bool useVersion = (spec->version != NULL); size_t hashStringSize = 0; if (useShortName) hashStringSize += strlen(spec->shortName); hashStringSize += 1; // for the '#' char if (useVersion) hashStringSize += strlen(spec->version); hashStringSize += 1; // for the '\0' char std::vector<char> hashString(hashStringSize, 0); if (useShortName) STRCAT_T(&hashString[0], hashStringSize, spec->shortName); STRCAT_T(&hashString[0], hashStringSize, "#"); if (useVersion) STRCAT_T(&hashString[0], hashStringSize, spec->version); return (string_simpleHash(&hashString[0])); }
bool GetJREPathFromBase(char* path, size_t pathSize, const char* basePath, const char* arch) { bool found = false; if (basePath != NULL) { //if (GetApplicationHome(path, pathSize)) { char jrePath[MAXPATHLEN]; // Is basePath a JRE path? STRCPY_T(jrePath, MAXPATHLEN, basePath); if (CheckIfJREPath(jrePath, arch)) { STRCPY_T(path, pathSize, basePath); found = true; } // Is basePath/jre a JRE path? STRCAT_T(jrePath, MAXPATHLEN, "\\jre"); if (CheckIfJREPath(jrePath, arch)) { STRCPY_T(path, pathSize, jrePath); found = true; } } return found; }
static void log_formatter_createPrefix_default(char** buffer, size_t* bufferSize, const char* section, int level) { (*buffer)[0] = '\0'; if (!LOG_SECTION_IS_DEFAULT(section)) { section = log_util_prepareSection(section); STRCAT_T(*buffer, *bufferSize, "["); STRCAT_T(*buffer, *bufferSize, section); STRCAT_T(*buffer, *bufferSize, "] "); } if (level != LOG_LEVEL_INFO) { const char* levelStr = log_util_levelToString(level); STRCAT_T(*buffer, *bufferSize, levelStr); STRCAT_T(*buffer, *bufferSize, ": "); } }
/** * Creates the Java library path. * -> where native shared libraries are searched * * It will consist of the following: * {spring-data-dir}/{AI_INTERFACES_DATA_DIR}/Java/{version}/ * {spring-data-dir}/{AI_INTERFACES_DATA_DIR}/Java/{version}/lib/ * {spring-data-dir}/{AI_INTERFACES_DATA_DIR}/Java/common/ * {spring-data-dir}/{AI_INTERFACES_DATA_DIR}/Java/common/lib/ */ static bool java_createNativeLibsPath(char* libraryPath, const size_t libraryPath_sizeMax) { // {spring-data-dir}/{AI_INTERFACES_DATA_DIR}/Java/{version}/ const char* const dd_r = callback->AIInterface_Info_getValueByKey(interfaceId, AI_INTERFACE_PROPERTY_DATA_DIR); if (dd_r == NULL) { simpleLog_logL(SIMPLELOG_LEVEL_ERROR, "Unable to find read-only data-dir."); return false; } else { STRCPY_T(libraryPath, libraryPath_sizeMax, dd_r); } // {spring-data-dir}/{AI_INTERFACES_DATA_DIR}/Java/{version}/lib/ char* dd_lib_r = callback->DataDirs_allocatePath(interfaceId, NATIVE_LIBS_DIR, false, false, true, false); if (dd_lib_r == NULL) { simpleLog_logL(SIMPLELOG_LEVEL_NORMAL, "Unable to find read-only native libs data-dir (optional): %s", NATIVE_LIBS_DIR); } else { STRCAT_T(libraryPath, libraryPath_sizeMax, ENTRY_DELIM); STRCAT_T(libraryPath, libraryPath_sizeMax, dd_lib_r); FREE(dd_lib_r); } // {spring-data-dir}/{AI_INTERFACES_DATA_DIR}/Java/common/ const char* const dd_r_common = callback->AIInterface_Info_getValueByKey(interfaceId, AI_INTERFACE_PROPERTY_DATA_DIR_COMMON); if (dd_r_common == NULL || !util_fileExists(dd_r_common)) { simpleLog_logL(SIMPLELOG_LEVEL_NORMAL, "Unable to find common read-only data-dir (optional)."); } else { STRCAT_T(libraryPath, libraryPath_sizeMax, ENTRY_DELIM); STRCAT_T(libraryPath, libraryPath_sizeMax, dd_r_common); } // {spring-data-dir}/{AI_INTERFACES_DATA_DIR}/Java/common/lib/ if (dd_r_common != NULL) { char* dd_lib_r_common = callback->DataDirs_allocatePath(interfaceId, NATIVE_LIBS_DIR, false, false, true, true); if (dd_lib_r_common == NULL || !util_fileExists(dd_lib_r_common)) { simpleLog_logL(SIMPLELOG_LEVEL_NORMAL, "Unable to find common read-only native libs data-dir (optional)."); } else { STRCAT_T(libraryPath, libraryPath_sizeMax, ENTRY_DELIM); STRCAT_T(libraryPath, libraryPath_sizeMax, dd_lib_r_common); FREE(dd_lib_r_common); } } return true; }
void AAIConfig::LoadConfig(AAI *ai) { // this size equals the one used in "AIAICallback::GetValue(AIVAL_LOCATE_FILE_..." char filename[2048]; char buffer[500]; MAX_UNITS = ai->Getcb()->GetMaxUnits(); FILE* file = NULL; STRCPY_T(buffer, sizeof(buffer), MAIN_PATH); STRCAT_T(buffer, sizeof(buffer), MOD_CFG_PATH); const std::string modHumanName = MakeFileSystemCompatible(ai->Getcb()->GetModHumanName()); STRCAT_T(buffer, sizeof(buffer), modHumanName.c_str()); STRCAT_T(buffer, sizeof(buffer), ".cfg"); STRCPY_T(filename, sizeof(filename), buffer); ai->Getcb()->GetValue(AIVAL_LOCATE_FILE_R, filename); file = fopen(filename, "r"); if (file == NULL) { ai->Log("Mod config file %s not found\n", filename); ai->Log("Now trying with legacy mod config file name ...\n"); STRCPY_T(buffer, sizeof(buffer), MAIN_PATH); STRCAT_T(buffer, sizeof(buffer), MOD_CFG_PATH); const std::string modName = MakeFileSystemCompatible(ai->Getcb()->GetModName()); STRCAT_T(buffer, sizeof(buffer), modName.c_str()); ReplaceExtension(buffer, filename, sizeof(filename), ".cfg"); ai->Getcb()->GetValue(AIVAL_LOCATE_FILE_R, filename); file = fopen(filename, "r"); } if (file == NULL) { ai->Log("Mod config file %s not found\n", filename); ai->Log("Now trying with version independent mod config file name ...\n"); STRCPY_T(buffer, sizeof(buffer), MAIN_PATH); STRCAT_T(buffer, sizeof(buffer), MOD_CFG_PATH); const std::string modShortName = MakeFileSystemCompatible(ai->Getcb()->GetModShortName()); STRCAT_T(buffer, sizeof(buffer), modShortName.c_str()); STRCAT_T(buffer, sizeof(buffer), ".cfg"); STRCPY_T(filename, sizeof(filename), buffer); ai->Getcb()->GetValue(AIVAL_LOCATE_FILE_R, filename); file = fopen(filename, "r"); } if (file == NULL) { ai->Log("Mod config file %s not found\n", filename); ai->Log("Give up trying to find mod config file (required).\n"); initialized = false; return; } char keyword[50]; int ival; float fval; const UnitDef *def; bool error = false; // bool loaded = false; if(file) { ai->Log("Using mod config file %s\n", filename); while(EOF != fscanf(file, "%s", keyword)) { if(!strcmp(keyword,"SIDES")) { fscanf(file, "%i", &ival); SIDES = ival; } else if(!strcmp(keyword, "START_UNITS")) { START_UNITS = new char*[SIDES]; for(int i = 0; i < SIDES; i++) { START_UNITS[i] = new char[20]; fscanf(file, "%s", filename); STRCPY(START_UNITS[i], filename); if(!ai->Getcb()->GetUnitDef(START_UNITS[i])) { ai->Log("ERROR: loading starting units - could not find unit %s\n", START_UNITS[i]); error = true; break; } } } else if(!strcmp(keyword, "SIDE_NAMES")) { SIDE_NAMES = new char*[SIDES]; for(int i = 0; i < SIDES; i++) { SIDE_NAMES[i] = new char[80]; fscanf(file, "%s", filename); STRCPY(SIDE_NAMES[i], filename); } } else if(!strcmp(keyword, "SCOUTS")) { // get number of scouts fscanf(file, "%i", &ival); for(int i = 0; i < ival; ++i) { fscanf(file, "%s", filename); if(ai->Getcb()->GetUnitDef(filename)) SCOUTS.push_back(ai->Getcb()->GetUnitDef(filename)->id); else { ai->Log("ERROR: loading scouts - could not find unit %s\n", filename); error = true; break; } } } else if(!strcmp(keyword, "ATTACKERS")) { // get number of attackers fscanf(file, "%i", &ival); for(int i = 0; i < ival; ++i) { fscanf(file, "%s", filename); if(ai->Getcb()->GetUnitDef(filename)) ATTACKERS.push_back(ai->Getcb()->GetUnitDef(filename)->id); else { ai->Log("ERROR: loading attackers - could not find unit %s\n", filename); error = true; break; } } } else if(!strcmp(keyword, "TRANSPORTERS")) { // get number of transporters fscanf(file, "%i", &ival); for(int i = 0; i < ival; ++i) { fscanf(file, "%s", filename); if(ai->Getcb()->GetUnitDef(filename)) TRANSPORTERS.push_back(ai->Getcb()->GetUnitDef(filename)->id); else { ai->Log("ERROR: loading transporters - could not find unit %s\n", filename); error = true; break; } } } else if(!strcmp(keyword, "DONT_BUILD")) { // get number of units that should not be built fscanf(file, "%i", &ival); for(int i = 0; i < ival; ++i) { fscanf(file, "%s", filename); if(ai->Getcb()->GetUnitDef(filename)) DONT_BUILD.push_back(ai->Getcb()->GetUnitDef(filename)->id); else { ai->Log("ERROR: loading dont_build units - could not find unit %s\n", filename); error = true; break; } } } else if(!strcmp(keyword, "COST_MULTIPLIER")) { // get the unit def fscanf(file, "%s", filename); def = ai->Getcb()->GetUnitDef(filename); if(def) { fscanf(file, "%f", &fval); CostMultiplier temp; temp.id = def->id; temp.multiplier = fval; cost_multipliers.push_back(temp); } else { ai->Log("ERROR: could not set cost multiplier - could not find unit %s\n", filename); error = true; break; } } else if(!strcmp(keyword,"SECTOR_SIZE")) { fscanf(file, "%f", &fval); SECTOR_SIZE = fval; ai->Log("SECTOR_SIZE set to %f", SECTOR_SIZE); } else if(!strcmp(keyword,"MIN_ENERGY")) { fscanf(file, "%i", &ival); MIN_ENERGY = ival; } else if(!strcmp(keyword, "MAX_UNITS")) { fscanf(file, "%i", &ival); MAX_UNITS = ival; } else if(!strcmp(keyword, "MAX_SCOUTS")) { fscanf(file, "%i", &ival); MAX_SCOUTS = ival; } else if(!strcmp(keyword, "MAX_SECTOR_IMPORTANCE")) { fscanf(file, "%i", &ival); MAX_SECTOR_IMPORTANCE = ival; } else if(!strcmp(keyword, "MAX_XROW")) { fscanf(file, "%i", &ival); MAX_XROW = ival; } else if(!strcmp(keyword, "MAX_YROW")) { fscanf(file, "%i", &ival); MAX_YROW = ival; } else if(!strcmp(keyword, "X_SPACE")) { fscanf(file, "%i", &ival); X_SPACE = ival; } else if(!strcmp(keyword, "Y_SPACE")) { fscanf(file, "%i", &ival); Y_SPACE = ival; } else if(!strcmp(keyword, "MAX_GROUP_SIZE")) { fscanf(file, "%i", &ival); MAX_GROUP_SIZE = ival; } else if(!strcmp(keyword, "MAX_AIR_GROUP_SIZE")) { fscanf(file, "%i", &ival); MAX_AIR_GROUP_SIZE = ival; } else if(!strcmp(keyword, "MAX_NAVAL_GROUP_SIZE")) { fscanf(file, "%i", &ival); MAX_NAVAL_GROUP_SIZE = ival; } else if(!strcmp(keyword, "MAX_SUBMARINE_GROUP_SIZE")) { fscanf(file, "%i", &ival); MAX_SUBMARINE_GROUP_SIZE = ival; } else if(!strcmp(keyword, "MAX_ANTI_AIR_GROUP_SIZE")) { fscanf(file, "%i", &ival); MAX_ANTI_AIR_GROUP_SIZE = ival; } else if(!strcmp(keyword, "MAX_ARTY_GROUP_SIZE")) { fscanf(file, "%i", &ival); MAX_ARTY_GROUP_SIZE = ival; } else if(!strcmp(keyword, "UNIT_SPEED_SUBGROUPS")) { fscanf(file, "%i", &ival); UNIT_SPEED_SUBGROUPS = ival; } else if(!strcmp(keyword, "FALLBACK_DIST_RATIO")) { fscanf(file, "%f", &fval); FALLBACK_DIST_RATIO = fval; } else if(!strcmp(keyword, "MIN_FALLBACK_RANGE")) { fscanf(file, "%f", &fval); MIN_FALLBACK_RANGE = fval; } else if(!strcmp(keyword, "MAX_FALLBACK_RANGE")) { fscanf(file, "%f", &fval); MAX_FALLBACK_RANGE = fval; } else if(!strcmp(keyword, "MIN_FALLBACK_TURNRATE")) { fscanf(file, "%f", &fval); MIN_FALLBACK_TURNRATE = fval; } else if(!strcmp(keyword, "MIN_EFFICIENCY")) { fscanf(file, "%f", &fval); MIN_EFFICIENCY = fval; } else if(!strcmp(keyword, "MIN_AIR_SUPPORT_EFFICIENCY")) { fscanf(file, "%f", &fval); MIN_AIR_SUPPORT_EFFICIENCY = fval; } else if(!strcmp(keyword, "MAX_BUILDERS")) { fscanf(file, "%i", &ival); MAX_BUILDERS = ival; } else if(!strcmp(keyword, "MAX_BUILDQUE_SIZE")) { fscanf(file, "%i", &ival); MAX_BUILDQUE_SIZE = ival; } else if(!strcmp(keyword, "MAX_ASSISTANTS")) { fscanf(file, "%i", &ival); MAX_ASSISTANTS = ival; } else if(!strcmp(keyword, "MIN_ASSISTANCE_BUILDSPEED")) { fscanf(file, "%i", &ival); MIN_ASSISTANCE_BUILDSPEED = ival; } else if(!strcmp(keyword, "MAX_BASE_SIZE")) { fscanf(file, "%i", &ival); MAX_BASE_SIZE = ival; } else if(!strcmp(keyword, "MAX_AIR_TARGETS")) { fscanf(file, "%i", &ival); MAX_AIR_TARGETS = ival; } else if(!strcmp(keyword, "MIN_AIR_ATTACK_COST")) { fscanf(file, "%i", &ival); MIN_AIR_ATTACK_COST = ival; } else if(!strcmp(keyword, "SCOUT_SPEED")) { fscanf(file, "%f", &fval); SCOUT_SPEED = fval; } else if(!strcmp(keyword, "GROUND_ARTY_RANGE")) { fscanf(file, "%f", &fval); GROUND_ARTY_RANGE = fval; } else if(!strcmp(keyword, "SEA_ARTY_RANGE")) { fscanf(file, "%f", &fval); SEA_ARTY_RANGE = fval; } else if(!strcmp(keyword, "HOVER_ARTY_RANGE")) { fscanf(file, "%f", &fval); HOVER_ARTY_RANGE = fval; } else if(!strcmp(keyword, "STATIONARY_ARTY_RANGE")) { fscanf(file, "%f", &fval); STATIONARY_ARTY_RANGE = fval; } else if(!strcmp(keyword, "MAX_BUILDERS_PER_TYPE")) { fscanf(file, "%i", &ival); MAX_BUILDERS_PER_TYPE = ival; } else if(!strcmp(keyword, "MAX_FACTORIES_PER_TYPE")) { fscanf(file, "%i", &ival); MAX_FACTORIES_PER_TYPE = ival; } else if(!strcmp(keyword, "MIN_ASSISTANCE_BUILDTIME")) { fscanf(file, "%i", &ival); MIN_ASSISTANCE_BUILDTIME = ival; } else if(!strcmp(keyword, "AIR_DEFENCE")) { fscanf(file, "%i", &ival); AIR_DEFENCE = ival; } else if(!strcmp(keyword, "AIRCRAFT_RATE")) { fscanf(file, "%i", &ival); AIRCRAFT_RATE = ival; } else if(!strcmp(keyword, "HIGH_RANGE_UNITS_RATE")) { fscanf(file, "%i", &ival); HIGH_RANGE_UNITS_RATE = ival; } else if(!strcmp(keyword, "FAST_UNITS_RATE")) { fscanf(file, "%i", &ival); FAST_UNITS_RATE = ival; } else if(!strcmp(keyword, "MAX_METAL_COST")) { fscanf(file, "%i", &ival); MAX_METAL_COST = ival; } else if(!strcmp(keyword, "MAX_DEFENCES")) { fscanf(file, "%i", &ival); MAX_DEFENCES = ival; } else if(!strcmp(keyword, "MIN_SECTOR_THREAT")) { fscanf(file, "%f", &fval); MIN_SECTOR_THREAT = fval; } else if(!strcmp(keyword, "MAX_STAT_ARTY")) { fscanf(file, "%i", &ival); MAX_STAT_ARTY = ival; } else if(!strcmp(keyword, "MAX_AIR_BASE")) { fscanf(file, "%i", &ival); MAX_AIR_BASE = ival; } else if(!strcmp(keyword, "AIR_ONLY_MOD")) { fscanf(file, "%i", &ival); AIR_ONLY_MOD = (bool)ival; } else if(!strcmp(keyword, "METAL_ENERGY_RATIO")) { fscanf(file, "%f", &fval); METAL_ENERGY_RATIO = fval; } else if(!strcmp(keyword, "NON_AMPHIB_MAX_WATERDEPTH")) { fscanf(file, "%f", &fval); NON_AMPHIB_MAX_WATERDEPTH = fval; } else if(!strcmp(keyword, "MAX_METAL_MAKERS")) { fscanf(file, "%i", &ival); MAX_METAL_MAKERS = ival; } else if(!strcmp(keyword, "MAX_STORAGE")) { fscanf(file, "%i", &ival); MAX_STORAGE = ival; } else if(!strcmp(keyword, "MIN_METAL_MAKER_ENERGY")) { fscanf(file, "%f", &fval); MIN_METAL_MAKER_ENERGY = fval; } else if(!strcmp(keyword, "MAX_MEX_DISTANCE")) { fscanf(file, "%i", &ival); MAX_MEX_DISTANCE = ival; } else if(!strcmp(keyword, "MAX_MEX_DEFENCE_DISTANCE")) { fscanf(file, "%i", &ival); MAX_MEX_DEFENCE_DISTANCE = ival; } else if(!strcmp(keyword, "MIN_FACTORIES_FOR_DEFENCES")) { fscanf(file, "%i", &ival); MIN_FACTORIES_FOR_DEFENCES = ival; } else if(!strcmp(keyword, "MIN_FACTORIES_FOR_STORAGE")) { fscanf(file, "%i", &ival); MIN_FACTORIES_FOR_STORAGE = ival; } else if(!strcmp(keyword, "MIN_FACTORIES_FOR_RADAR_JAMMER")) { fscanf(file, "%i", &ival); MIN_FACTORIES_FOR_RADAR_JAMMER = ival; } else if(!strcmp(keyword, "MIN_SUBMARINE_WATERLINE")) { fscanf(file, "%i", &ival); MIN_SUBMARINE_WATERLINE = ival; } else if(!strcmp(keyword, "MAX_ATTACKS")) { fscanf(file, "%i", &ival); MAX_ATTACKS = ival; } else { error = true; break; } } if(error) { ai->Log("Mod config file %s contains erroneous keyword %s\n", filename, keyword); initialized = false; return; } else { // loaded = true; fclose(file); ai->Log("Mod config file loaded\n"); } } // load general settings STRCPY_T(buffer, sizeof(buffer), MAIN_PATH); STRCAT_T(buffer, sizeof(buffer), GENERAL_CFG_FILE); ReplaceExtension(buffer, filename, sizeof(filename), ".cfg"); ai->Getcb()->GetValue(AIVAL_LOCATE_FILE_R, filename); file = fopen(filename, "r"); if(file) { while(EOF != fscanf(file, "%s", keyword)) { if(!strcmp(keyword, "LEARN_RATE")) { fscanf(file, "%i", &ival); LEARN_RATE = ival; } else if(!strcmp(keyword, "LEARN_SPEED")) { fscanf(file, "%f", &fval); LEARN_SPEED = fval; } else if(!strcmp(keyword, "WATER_MAP_RATIO")) { fscanf(file, "%f", &fval); WATER_MAP_RATIO = fval; } else if(!strcmp(keyword, "LAND_WATER_MAP_RATIO")) { fscanf(file, "%f", &fval); LAND_WATER_MAP_RATIO = fval; } else if(!strcmp(keyword, "SCOUT_UPDATE_FREQUENCY")) { fscanf(file, "%i", &ival); SCOUT_UPDATE_FREQUENCY = ival; } else if(!strcmp(keyword, "SCOUTING_MEMORY_FACTOR")) { fscanf(file, "%f", &fval); SCOUTING_MEMORY_FACTOR = fval; } else { error = true; break; } } fclose(file); if(error) { ai->Log("General config file %s contains erroneous keyword %s\n", filename, keyword); initialized = false; return; } else { ai->Log("General config file loaded\n"); initialized = true; return; } } else { ai->Log("General config file %s not found\n", filename); initialized = false; return; } }
static bool java_createJavaVMInitArgs(struct JavaVMInitArgs* vm_args, const struct Properties* jvmProps) { // ### evaluate JNI version to use ### //jint jniVersion = JNI_VERSION_1_1; //jint jniVersion = JNI_VERSION_1_2; jint jniVersion = JNI_VERSION_1_4; //jint jniVersion = JNI_VERSION_1_6; if (jvmProps != NULL) { const char* jniVersionFromCfg = java_getValueByKey(jvmProps, "jvm.jni.version"); if (jniVersionFromCfg != NULL) { unsigned long int jniVersion_tmp = strtoul(jniVersionFromCfg, NULL, 16); if (jniVersion_tmp != 0/* && jniVersion_tmp != ULONG_MAX*/) { jniVersion = (jint) jniVersion_tmp; } } } simpleLog_logL(SIMPLELOG_LEVEL_FINE, "JVM: JNI version: %#x", jniVersion); vm_args->version = jniVersion; // ### check if debug related JVM options should be used ### // if false, the JVM creation will fail if an // unknown or invalid option was specified bool useDebugOptions = true; const char* useDebugOptionsStr = "auto"; if (jvmProps != NULL) { const char* useDebugOptionsFromCfg = util_map_getValueByKey( jvmProps->size, jvmProps->keys, jvmProps->values, "jvm.useDebugOptions"); if (useDebugOptionsFromCfg != NULL) { useDebugOptionsStr = useDebugOptionsFromCfg; } } { if (strcmp(useDebugOptionsStr, "auto") == 0 || strcmp(useDebugOptionsStr, "Auto") == 0 || strcmp(useDebugOptionsStr, "AUTO") == 0 || strcmp(useDebugOptionsStr, "a") == 0 || strcmp(useDebugOptionsStr, "A") == 0) { // auto #if defined DEBUG useDebugOptions = true; #else // defined DEBUG useDebugOptions = false; #endif // defined DEBUG } else { // true or false useDebugOptions = util_strToBool(useDebugOptionsStr); } } // ### check if unrecognized JVM options should be ignored ### // if false, the JVM creation will fail if an // unknown or invalid option was specified bool ignoreUnrecognized = true; if (jvmProps != NULL) { const char* ignoreUnrecognizedFromCfg = java_getValueByKey(jvmProps, "jvm.arguments.ignoreUnrecognized"); if (ignoreUnrecognizedFromCfg != NULL && !util_strToBool(ignoreUnrecognizedFromCfg)) { ignoreUnrecognized = false; } } if (ignoreUnrecognized) { simpleLog_logL(SIMPLELOG_LEVEL_FINE, "JVM: ignoring unrecognized options"); vm_args->ignoreUnrecognized = JNI_TRUE; } else { simpleLog_logL(SIMPLELOG_LEVEL_FINE, "JVM: NOT ignoring unrecognized options"); vm_args->ignoreUnrecognized = JNI_FALSE; } // ### create the Java class-path option ### // autogenerate the class path static const size_t classPath_sizeMax = 8 * 1024; char* classPath = util_allocStr(classPath_sizeMax); // ..., autogenerate it ... if (!java_createClassPath(classPath, classPath_sizeMax)) { simpleLog_logL(SIMPLELOG_LEVEL_ERROR, "Failed creating Java class-path."); return false; } if (jvmProps != NULL) { // ..., and append the part from the jvm options properties file, // if it is specified there const char* clsPathFromCfg = java_getValueByKey(jvmProps, "jvm.option.java.class.path"); if (clsPathFromCfg != NULL) { STRCAT_T(classPath, classPath_sizeMax, ENTRY_DELIM); STRCAT_T(classPath, classPath_sizeMax, clsPathFromCfg); } } // create the java.class.path option static const size_t classPathOpt_sizeMax = 8 * 1024; char* classPathOpt = util_allocStr(classPathOpt_sizeMax); STRCPY_T(classPathOpt, classPathOpt_sizeMax, "-Djava.class.path="); STRCAT_T(classPathOpt, classPathOpt_sizeMax, classPath); FREE(classPath); // ### create the Java library-path option ### // autogenerate the java library path static const size_t libraryPath_sizeMax = 4 * 1024; char* libraryPath = util_allocStr(libraryPath_sizeMax); // ..., autogenerate it ... if (!java_createNativeLibsPath(libraryPath, libraryPath_sizeMax)) { simpleLog_logL(SIMPLELOG_LEVEL_ERROR, "Failed creating Java library-path."); return false; } if (jvmProps != NULL) { // ..., and append the part from the jvm options properties file, // if it is specified there const char* libPathFromCfg = java_getValueByKey(jvmProps, "jvm.option.java.library.path"); if (libPathFromCfg != NULL) { STRCAT_T(libraryPath, libraryPath_sizeMax, ENTRY_DELIM); STRCAT_T(libraryPath, libraryPath_sizeMax, libPathFromCfg); } } // create the java.library.path option ... // autogenerate it, and append the part from the jvm options file, // if it is specified there static const size_t libraryPathOpt_sizeMax = 4 * 1024; char* libraryPathOpt = util_allocStr(libraryPathOpt_sizeMax); STRCPY_T(libraryPathOpt, libraryPathOpt_sizeMax, "-Djava.library.path="); STRCAT_T(libraryPathOpt, libraryPathOpt_sizeMax, libraryPath); FREE(libraryPath); // ### create and set all JVM options ### static const size_t strOptions_sizeMax = 64; const char* strOptions[strOptions_sizeMax]; size_t op = 0; strOptions[op++] = classPathOpt; strOptions[op++] = libraryPathOpt; static const char* const JCPVAL = "-Djava.class.path="; const size_t JCPVAL_size = strlen(JCPVAL); static const char* const JLPVAL = "-Djava.library.path="; const size_t JLPVAL_size = strlen(JCPVAL); if (jvmProps != NULL) { // ### add string options from the JVM config file with property name "jvm.option.x" ### int i; for (i=0; i < jvmProps->size; ++i) { if (strcmp(jvmProps->keys[i], "jvm.option.x") == 0 || (useDebugOptions && (strcmp(jvmProps->keys[i], "jvm.option.debug.x") == 0))) { const char* const val = jvmProps->values[i]; const size_t val_size = strlen(val); // ignore "-Djava.class.path=..." // and "-Djava.library.path=..." options if (strncmp(val, JCPVAL, minSize(val_size, JCPVAL_size)) != 0 && strncmp(val, JLPVAL, minSize(val_size, JLPVAL_size)) != 0) { strOptions[op++] = val; } } } } else { // ### ... or set default ones, if the JVM config file was not found ### simpleLog_logL(SIMPLELOG_LEVEL_WARNING, "JVM: properties file ("JVM_PROPERTIES_FILE") not found; using default options."); strOptions[op++] = "-Xms4M"; strOptions[op++] = "-Xmx64M"; strOptions[op++] = "-Xss512K"; strOptions[op++] = "-Xoss400K"; #if defined DEBUG strOptions[op++] = "-Xcheck:jni"; strOptions[op++] = "-verbose:jni"; strOptions[op++] = "-XX:+UnlockDiagnosticVMOptions"; strOptions[op++] = "-XX:+LogVMOutput"; strOptions[op++] = "-Xdebug"; strOptions[op++] = "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=7777"; // disable JIT (required for debugging under the classical VM) strOptions[op++] = "-Djava.compiler=NONE"; // disable old JDB strOptions[op++] = "-Xnoagent"; #endif // defined DEBUG } const size_t options_size = op; vm_args->options = (struct JavaVMOption*) calloc(options_size, sizeof(struct JavaVMOption)); // fill strOptions into the JVM options simpleLog_logL(SIMPLELOG_LEVEL_FINE, "JVM: options:", options_size); char* dd_rw = callback->DataDirs_allocatePath(interfaceId, "", true, true, true, false); size_t i; jint nOptions = 0; for (i = 0; i < options_size; ++i) { char* tmpOptionString = util_allocStrReplaceStr(strOptions[i], "${home-dir}", dd_rw); // do not add empty options if (tmpOptionString != NULL) { if (strlen(tmpOptionString) > 0) { vm_args->options[nOptions].optionString = tmpOptionString; vm_args->options[nOptions].extraInfo = NULL; simpleLog_logL(SIMPLELOG_LEVEL_FINE, "JVM option %ul: %s", nOptions, tmpOptionString); nOptions++; } else { free(tmpOptionString); tmpOptionString = NULL; } } } vm_args->nOptions = nOptions; FREE(dd_rw); FREE(classPathOpt); FREE(libraryPathOpt); simpleLog_logL(SIMPLELOG_LEVEL_FINE, ""); return true; }
/** * Creates the AI Interface global Java class path. * * It will consist of the following: * {spring-data-dir}/{AI_INTERFACES_DATA_DIR}/Java/{version}/AIInterface.jar * {spring-data-dir}/{AI_INTERFACES_DATA_DIR}/Java/{version}/(j)?config/ * {spring-data-dir}/{AI_INTERFACES_DATA_DIR}/Java/{version}/(j)?config/[*].jar * {spring-data-dir}/{AI_INTERFACES_DATA_DIR}/Java/{version}/(j)?resources/ * {spring-data-dir}/{AI_INTERFACES_DATA_DIR}/Java/{version}/(j)?resources/[*].jar * {spring-data-dir}/{AI_INTERFACES_DATA_DIR}/Java/{version}/(j)?script/ * {spring-data-dir}/{AI_INTERFACES_DATA_DIR}/Java/{version}/(j)?script/[*].jar * {spring-data-dir}/{AI_INTERFACES_DATA_DIR}/Java/{version}/jlib/ * {spring-data-dir}/{AI_INTERFACES_DATA_DIR}/Java/{version}/jlib/[*].jar * TODO: {spring-data-dir}/{AI_INTERFACES_DATA_DIR}/Java/common/jlib/ * TODO: {spring-data-dir}/{AI_INTERFACES_DATA_DIR}/Java/common/jlib/[*].jar */ static size_t java_createClassPath(char* classPathStr, const size_t classPathStr_sizeMax) { // the dirs and .jar files in the following array // will be concatenated with intermediate path separators // to form the classPathStr static const size_t classPath_sizeMax = 128; char** classPath = (char**) calloc(classPath_sizeMax, sizeof(char*)); size_t classPath_size = 0; // the Java AI Interfaces java library file path (.../AIInterface.jar) // We need to search for this jar, instead of looking only where // the AIInterface.so/InterfaceInfo.lua is, because on some systems // (eg. Debian), the .so is in /usr/lib, and the .jar's are in /usr/shared. char* mainJarPath = callback->DataDirs_allocatePath(interfaceId, JAVA_AI_INTERFACE_LIBRARY_FILE_NAME, false, false, false, false); classPath[classPath_size++] = util_allocStrCpy(mainJarPath); bool ok = util_getParentDir(mainJarPath); if (!ok) { simpleLog_logL(SIMPLELOG_LEVEL_ERROR, "Retrieving the parent dir of the path to AIInterface.jar (%s) failed.", mainJarPath); } char* jarsDataDir = mainJarPath; mainJarPath = NULL; // the directories in the following list will be searched for .jar files // which will then be added to the classPathStr, plus the dirs will be added // to the classPathStr directly, so you can keep .class files in there static const size_t jarDirs_sizeMax = 128; char** jarDirs = (char**) calloc(jarDirs_sizeMax, sizeof(char*)); size_t jarDirs_size = 0; // add to classpath: // {spring-data-dir}/Interfaces/Java/0.1/${x}/ jarDirs[jarDirs_size++] = util_allocStrCatFSPath(2, jarsDataDir, "jconfig"); jarDirs[jarDirs_size++] = util_allocStrCatFSPath(2, jarsDataDir, "config"); jarDirs[jarDirs_size++] = util_allocStrCatFSPath(2, jarsDataDir, "jresources"); jarDirs[jarDirs_size++] = util_allocStrCatFSPath(2, jarsDataDir, "resources"); jarDirs[jarDirs_size++] = util_allocStrCatFSPath(2, jarsDataDir, "jscript"); jarDirs[jarDirs_size++] = util_allocStrCatFSPath(2, jarsDataDir, "script"); jarDirs[jarDirs_size++] = util_allocStrCatFSPath(2, jarsDataDir, "jlib"); // "lib" is for native libs only // add the jar dirs (for .class files) and all contained .jars recursively size_t jd, jf; for (jd=0; (jd < jarDirs_size) && (classPath_size < classPath_sizeMax); ++jd) { if (util_fileExists(jarDirs[jd])) { // add the dir directly // For this to work properly with URLClassPathHandler, // we have to ensure there is a '/' at the end, // for the class-path-part to be recognized as a directory. classPath[classPath_size++] = util_allocStrCat(2, jarDirs[jd], "/"); // add the contained jars recursively static const size_t jarFiles_sizeMax = 128; char** jarFiles = (char**) calloc(jarFiles_sizeMax, sizeof(char*)); const size_t jarFiles_size = util_listFiles(jarDirs[jd], ".jar", jarFiles, true, jarFiles_sizeMax); for (jf=0; (jf < jarFiles_size) && (classPath_size < classPath_sizeMax); ++jf) { classPath[classPath_size++] = util_allocStrCatFSPath(2, jarDirs[jd], jarFiles[jf]); FREE(jarFiles[jf]); } FREE(jarFiles); } FREE(jarDirs[jd]); } FREE(jarDirs); // concat the classpath entries classPathStr[0] = '\0'; if (classPath[0] != NULL) { STRCAT_T(classPathStr, classPathStr_sizeMax, classPath[0]); FREE(classPath[0]); } size_t cp; for (cp=1; cp < classPath_size; ++cp) { if (classPath[cp] != NULL) { STRCAT_T(classPathStr, classPathStr_sizeMax, ENTRY_DELIM); STRCAT_T(classPathStr, classPathStr_sizeMax, classPath[cp]); FREE(classPath[cp]); } } FREE(classPath); return classPath_size; }