Skip to content

Commit

Permalink
Add support for .cgpr files into GPR project handling
Browse files Browse the repository at this point in the history
  • Loading branch information
HugoGGuerrier committed May 29, 2024
1 parent 6c97ac7 commit 6490b69
Show file tree
Hide file tree
Showing 32 changed files with 501 additions and 94 deletions.
4 changes: 2 additions & 2 deletions ada/documentation.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@
""",
'libadalang.gpr_project_load_implicit': """
Load an implicit project in the current directory. This function uses
This function uses ``GNATCOLL.Projects.Load_Implicit_Project`` to load
the ``_default.gpr`` project file.
``GNATCOLL.Projects.Load_Implicit_Project`` to load the
``_default.gpr`` project file.
""",
'libadalang.gpr_project_free': """
Free resources allocated for ``Self``.
Expand Down
2 changes: 2 additions & 0 deletions extensions/analysis/c_api/header
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ ${capi.get_name('gpr_project_load')}(
const ${scn_var_type} *scenario_vars,
const char *target,
const char *runtime,
const char *config_file,
${project_type} *project,
${str_array_type} *errors
);
Expand All @@ -50,6 +51,7 @@ extern void
${capi.get_name('gpr_project_load_implicit')}(
const char *target,
const char *runtime,
const char *config_file,
${project_type} *project,
${str_array_type} *errors
);
Expand Down
1 change: 1 addition & 0 deletions extensions/java_api/jni_funcs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ nat = c_api.get_name
ScenarioVariable[] scenarioVariables,
String target,
String runtime,
String configFile,
List<String> diagnostics
);

Expand Down
19 changes: 15 additions & 4 deletions extensions/java_api/jni_impl
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ ${api.jni_func_sig("gpr_project_load", "jobject")}(
jobjectArray scenario_variables,
jstring target,
jstring runtime,
jstring config_file,
jobject diagnostics
) {
// Create the scenario variable array
Expand Down Expand Up @@ -128,8 +129,9 @@ ${api.jni_func_sig("gpr_project_load", "jobject")}(
}

// Create the common project arguments
const char *target_c = to_c_string(env, target);
const char *runtime_c = to_c_string(env, runtime);
const char *target_c = target == NULL ? NULL : to_c_string(env, target);
const char *runtime_c = runtime == NULL ? NULL : to_c_string(env, runtime);
const char *config_file_c = config_file == NULL ? NULL : to_c_string(env, config_file);
${project_type} res = NULL;
${str_array_type} errors = NULL;

Expand All @@ -139,6 +141,7 @@ ${api.jni_func_sig("gpr_project_load", "jobject")}(
${nat("gpr_project_load_implicit")}(
target_c,
runtime_c,
config_file_c,
&res,
&errors
);
Expand All @@ -149,6 +152,7 @@ ${api.jni_func_sig("gpr_project_load", "jobject")}(
scenario_variables_native,
target_c,
runtime_c,
config_file_c,
&res,
&errors
);
Expand All @@ -164,8 +168,15 @@ ${api.jni_func_sig("gpr_project_load", "jobject")}(
}

// Free the translated strings
(*env)->ReleaseStringUTFChars(env, target, target_c);
(*env)->ReleaseStringUTFChars(env, runtime, runtime_c);
if (target_c != NULL) {
(*env)->ReleaseStringUTFChars(env, target, target_c);
}
if (runtime_c != NULL) {
(*env)->ReleaseStringUTFChars(env, runtime, runtime_c);
}
if (config_file_c != NULL) {
(*env)->ReleaseStringUTFChars(env, config_file, config_file_c);
}

// The `errors` pointer is not allocated if an exception was raised during
// project file loading.
Expand Down
73 changes: 51 additions & 22 deletions extensions/java_api/main_class
Original file line number Diff line number Diff line change
Expand Up @@ -265,56 +265,68 @@ nat = c_api.get_name
* Create a project manager for the given project file.
*
* @param projectFile The GPR project file to load.
* @return The newly created project manager.
*/
public static ProjectManager create(
final String projectFile
) {
return create(
return internalCreate(
projectFile,
null,
"",
""
null,
null,
null
);
}

/**
* Create a project manager from a project file, target and runtime. If the
* project file is null, then an implicit project is loaded.
*
* @param projectFile The GPR file to load.
* @param scenarioVariables The scenario variables for the project, it can be null.
* @param target The target to load.
* @param runtime The runtime to load.
* @return The newly created project manager.
* @param projectFile The GPR project file to use, if any. If null, an
* implicit project will be loaded.
* @param scenarioVariables Scenario variables to use during the
* project loading. This can be null.
* @param target Ada target to use. This can be null.
* @param runtime Ada runtime to use. This can be null.
* @param configFile The absolute path to a .cgpr file to use during
* the project loading. This can be null.
*/
public static ProjectManager create(
final String projectFile,
final ScenarioVariable[] scenarioVariables,
final String target,
final String runtime
final String runtime,
final String configFile
) {
return internalCreate(
projectFile,
scenarioVariables,
target,
runtime
runtime,
configFile
);
}

/**
* Create a project manager for an implicit project. The current directory
* is used as project source directory.
*
* @param target Ada target to use. This can be null.
* @param runtime Ada runtime to use. This can be null.
* @param configFile The absolute path to a .cgpr file to use during
* the project loading. This can be null.
*/
public static ProjectManager createImplicit(
final String target,
final String runtime
final String runtime,
final String configFile
) {
return internalCreate(
null,
null,
target,
runtime
runtime,
configFile
);
}

Expand All @@ -324,19 +336,31 @@ nat = c_api.get_name
*
* @param projectFile The GPR project file to use, if any. If null, an
* implicit project will be loaded.
* @param scenarioVariables Scenario variables to use during the
* project loading. This can be null.
* @param target Ada target to use. This can be null.
* @param runtime Ada runtime to use. This can be null.
* @param configFile The absolute path to a .cgpr file to use during
* the project loading. This can be null.
*/
private static ProjectManager internalCreate(
final String projectFile,
final ScenarioVariable[] scenarioVariables,
final String target,
final String runtime
final String runtime,
final String configFile
) {

if(ImageInfo.inImageCode()) {
// Create the scenario variable array
// Declare native values
final Pointer scenarioVariablesNative;
final int scenarioVariableNativeSize = SizeOf.get(ScenarioVariableNative.class);
final CCharPointer targetNative;
final CCharPointer runtimeNative;
final CCharPointer configFileNative;
final Pointer errorsPointer;

// Create the scenario variable array
final int scenarioVariableNativeSize = SizeOf.get(ScenarioVariableNative.class);
if(scenarioVariables != null && scenarioVariables.length > 0) {
final int size = scenarioVariables.length + 1;
scenarioVariablesNative = UnmanagedMemory.calloc(
Expand All @@ -355,10 +379,11 @@ nat = c_api.get_name
final Pointer projectPointer = StackValue.get(SizeOf.get(VoidPointer.class));
projectPointer.writeWord(0, WordFactory.nullPointer());

// Create the common native arguments
final CCharPointer targetNative = toCString(target);
final CCharPointer runtimeNative = toCString(runtime);
final Pointer errorsPointer = StackValue.get(SizeOf.get(VoidPointer.class));
// Fill the native arguments
targetNative = target == null ? WordFactory.nullPointer() : toCString(target);
runtimeNative = runtime == null ? WordFactory.nullPointer() : toCString(runtime);
configFileNative = configFile == null ? WordFactory.nullPointer() : toCString(configFile);
errorsPointer = StackValue.get(SizeOf.get(WordPointer.class));
errorsPointer.writeWord(0, WordFactory.nullPointer());

// If the provided project file is null, call the implicit project loading.
Expand All @@ -367,6 +392,7 @@ nat = c_api.get_name
NI_LIB.${nat("gpr_project_load_implicit")}(
targetNative,
runtimeNative,
configFileNative,
projectPointer,
errorsPointer
);
Expand All @@ -377,15 +403,17 @@ nat = c_api.get_name
scenarioVariablesNative,
targetNative,
runtimeNative,
configFileNative,
projectPointer,
errorsPointer
);
UnmanagedMemory.free(projectFileNative);
}

// Free the allocated strings
UnmanagedMemory.free(targetNative);
UnmanagedMemory.free(runtimeNative);
if (target != null) UnmanagedMemory.free(targetNative);
if (runtime != null) UnmanagedMemory.free(runtimeNative);
if (configFile != null) UnmanagedMemory.free(configFileNative);

// Check the langkit exception and cast it into a project manager error
try {
Expand Down Expand Up @@ -440,6 +468,7 @@ nat = c_api.get_name
scenarioVariables,
target,
runtime,
configFile,
diagnostics
);

Expand Down
2 changes: 2 additions & 0 deletions extensions/java_api/ni_funcs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ nat = c_api.get_name
Pointer scenarioVariable,
CCharPointer target,
CCharPointer runtime,
CCharPointer configFile,
Pointer project,
Pointer errors
);
Expand All @@ -24,6 +25,7 @@ nat = c_api.get_name
public static native void ${nat("gpr_project_load_implicit")}(
CCharPointer target,
CCharPointer runtime,
CCharPointer configFile,
Pointer project,
Pointer errors
);
Expand Down
5 changes: 3 additions & 2 deletions extensions/ocaml_api/module_struct
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ module GPRProject = struct
let gpr_project_load =
foreign ~from:c_lib "${capi.get_name("gpr_project_load")}"
(string @-> project_scenario_variable @-> string
@-> string @-> ptr c_type @-> ptr string_array @-> raisable void)
@-> string @-> string @-> ptr c_type @-> ptr string_array @-> raisable void)

let gpr_project_create_preprocessor =
foreign ~from:c_lib "${capi.get_name("gpr_project_create_preprocessor")}"
Expand All @@ -101,7 +101,8 @@ module GPRProject = struct
(* Use allocate_n to avoid having to give it an initial value *)
let result = allocate_n ~count:1 c_type in
let errors = allocate_n ~count:1 string_array in
gpr_project_load project_file scenario_vars target runtime result errors ;
gpr_project_load
project_file scenario_vars target runtime "" result errors ;
(* Not sure what to do with errors here as we already have an exception *)
!@ result

Expand Down
4 changes: 4 additions & 0 deletions extensions/python
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ class GPRProject:
scenario_vars: Dict[str, str] = {},
target: Opt[str] = None,
runtime: Opt[str] = None,
config_file: Opt[str] = None,
print_errors: bool = True):
"""
Load a GPR project file.
Expand All @@ -152,6 +153,7 @@ class GPRProject:
c_project_file = _coerce_bytes('project_file', project_file)
c_target = _coerce_bytes('target', target, or_none=True)
c_runtime = _coerce_bytes('runtime', runtime, or_none=True)
c_config_file = _coerce_bytes('config_file', config_file, or_none=True)

if scenario_vars:
items = scenario_vars.items()
Expand All @@ -178,6 +180,7 @@ class GPRProject:
c_scenario_vars,
c_target,
c_runtime,
c_config_file,
ctypes.byref(c_project),
ctypes.byref(c_errors),
)
Expand Down Expand Up @@ -377,6 +380,7 @@ class GPRProject:
ctypes.POINTER(_c_scenario_variable),
ctypes.c_char_p,
ctypes.c_char_p,
ctypes.c_char_p,
ctypes.POINTER(_c_type),
ctypes.POINTER(_c_string_array_ptr)],
None,
Expand Down
Loading

0 comments on commit 6490b69

Please sign in to comment.