public static FunctionDefinitionDataType parseSignature(DataTypeManagerService service,
			Program program, String signatureText, boolean handleExceptions) throws ParseException {

		DataTypeManager[] dataTypeManagers = service != null ? getDataTypeManagers(service)
				: new DataTypeManager[] { program.getDataTypeManager() };

		CParser parser = new CParser(program.getDataTypeManager(), false, dataTypeManagers);

		String[] signatureParts = splitFunctionSignature(signatureText);
		if (signatureParts == null) {
			Msg.debug(CParserUtils.class,
				"Invalid signature: unable to isolate function name : " + signatureText);
			return null;
		}

		String replacedText =
			signatureParts[0] + " " + getTempName(signatureParts[1].length()) + signatureParts[2];

		DataType dt = null;
		try {
			// parse the signature
			parser.setParseFileName("input line");
			dt = parser.parse(replacedText + ";");

			if (!(dt instanceof FunctionDefinitionDataType)) {
				return null;
			}

			// put back the old signature name
			dt.setName(signatureParts[1]);

			return (FunctionDefinitionDataType) dt;
		}
		catch (InvalidNameException | DuplicateNameException e) {
			// can't happen since we are calling setName() with the value that was 
			// previously set (this can change in the future if we ever modify the 
			// name before we restore it) 
			Msg.debug(CParserUtils.class,
				"Logging an exception that cannot happen (the code must have changed)", e);
		}
		catch (Throwable t) {
			if (!handleExceptions) {
				throw t;
			}

			String msg = handleParseProblem(t, signatureText);
			if (msg != null) {
				Msg.showError(CParserUtils.class, null, "Invalid Function Signature", msg);
			}
			else {
				Msg.debug(CParserUtils.class, "Error parsing signature: " + signatureText, t);
			}

		}

		return null;
	}
Parse the given function signature text.  Any exceptions will be handled herein
by showing an error dialog (null is returned in that case).

@param service the service used to access DataTypeManagers or null to use only the program's
data type manager.
@param program the program against which data types will be resolved
@param signatureText the signature to parse
@param handleExceptions true signals that this method should deal with exceptions, 
       showing error messages as necessary; false signals to throw any encountered
       parsing exceptions.  This allows clients to perform exception handling that
       better matches their workflow.
@return the data type that is created as a result of parsing; null if there was a problem
@throws ParseException for catastrophic errors in C parsing
Ghidra/Features/Base/src/main/java/ghidra/app/util/cparser/C/CParserUtils.java