summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrancesco Romani <fromani@gmail.com>2014-07-05 18:02:13 +0200
committerSebastian Dröge <sebastian@centricular.com>2023-04-12 19:26:53 +0300
commit615d6129f465cc2286d842e51aadf3703766505c (patch)
treeac8fc4a62ef14f902ae05aa751e819cca82bf5dd
parent1edcce3775d163bc47a8f83a57ede2395174abc6 (diff)
downloadorc-615d6129f465cc2286d842e51aadf3703766505c.tar.gz
program: add orc_program_append_str_n
Add a new API which generalizes orc_program_append_str_2 which * supports any number of operands for the given opcode * reports the status of the operation most notably, in case of unknown operand, the new API signals the wrong operand. Co-authored-by: Sebastian Dröge <sebastian@centricular.com> Part-of: <https://gitlab.freedesktop.org/gstreamer/orc/-/merge_requests/30>
-rw-r--r--orc/orcprogram.c135
-rw-r--r--orc/orcprogram.h2
2 files changed, 98 insertions, 39 deletions
diff --git a/orc/orcprogram.c b/orc/orcprogram.c
index 2ad2bc4..de6c76f 100644
--- a/orc/orcprogram.c
+++ b/orc/orcprogram.c
@@ -909,26 +909,19 @@ void
orc_program_append_str (OrcProgram *program, const char *name,
const char *arg1, const char *arg2, const char *arg3)
{
- OrcInstruction *insn;
-
- insn = program->insns + program->n_insns;
-
- insn->opcode = orc_opcode_find_by_name (name);
- if (!insn->opcode) {
- ORC_ERROR ("unknown opcode: %s", name);
- orc_program_set_error (program, "unknown opcode");
- return;
- }
- insn->dest_args[0] = orc_program_find_var_by_name (program, arg1);
- if (insn->opcode->dest_size[1] != 0) {
- insn->dest_args[1] = orc_program_find_var_by_name (program, arg2);
- insn->src_args[0] = orc_program_find_var_by_name (program, arg3);
- } else {
- insn->src_args[0] = orc_program_find_var_by_name (program, arg2);
- insn->src_args[1] = orc_program_find_var_by_name (program, arg3);
- }
-
- program->n_insns++;
+ const char *args[3] = { arg1, arg2, arg3 };
+ int argc;
+
+ if (arg3)
+ argc = 3;
+ else if (arg2)
+ argc = 2;
+ else if (arg1)
+ argc = 1;
+ else
+ argc = 0;
+
+ orc_program_append_str_n (program, name, 0, argc, args);
}
/**
@@ -949,45 +942,109 @@ orc_program_append_str_2 (OrcProgram *program, const char *name,
unsigned int flags, const char *arg1, const char *arg2, const char *arg3,
const char *arg4)
{
+ const char *args[4] = { arg1, arg2, arg3, arg4 };
+ int argc;
+
+ if (arg4)
+ argc = 4;
+ else if (arg3)
+ argc = 3;
+ else if (arg2)
+ argc = 2;
+ else if (arg1)
+ argc = 1;
+ else
+ argc = 0;
+
+ orc_program_append_str_n (program, name, flags, argc, args);
+}
+
+/**
+ * orc_program_append_str_n:
+ * @program: a pointer to an OrcProgram structure
+ * @name: name of instruction
+ * @flags: flags
+ * @argc: number of variableds
+ * @argv: array of variables
+ *
+ * Appends an instruction to the program, with any number of
+ * arguments. Only 1 <= number <= 6 is supported.
+ *
+ * Returns: status code.
+ * 0: succesfull
+ * <0: malformed opcode (unknown or bad arguments)
+ * >0: unknown argument. Then the return value equals to the nth
+ * argument. Beware: this is index, not offset (the first is 1).
+ */
+int
+orc_program_append_str_n (OrcProgram *program, const char *name,
+ unsigned int flags, int argc, const char **argv)
+{
OrcInstruction *insn;
- int args[4];
+ int args[6];
int i;
+ int expected_args = 0;
insn = program->insns + program->n_insns;
insn->line = program->current_line;
insn->opcode = orc_opcode_find_by_name (name);
if (!insn->opcode) {
- ORC_ERROR ("unknown opcode: %s at line %d", name, insn->line);
+ ORC_ERROR ("unknown opcode: %s", name);
orc_program_set_error (program, "unknown opcode");
- return;
+ return -1;
}
- if (insn->opcode->dest_size[1] != 0 && insn->opcode->src_size[2] != 0) {
- ORC_ERROR ("opcode has too many dest/src parameters: %s", name);
- orc_program_set_error (program, "opcode has too many dest/src parameters");
- return;
+
+ /* dest_size[0] */
+ expected_args++;
+ if (insn->opcode->dest_size[1] != 0)
+ expected_args++;
+ if (insn->opcode->src_size[0] != 0)
+ expected_args++;
+ if (insn->opcode->src_size[1] != 0)
+ expected_args++;
+ if (insn->opcode->src_size[2] != 0)
+ expected_args++;
+ if (insn->opcode->src_size[3] != 0)
+ expected_args++;
+
+ if (argc < expected_args) {
+ ORC_ERROR ("not the correct number of arguments provided for opcode: %s expects %d but got %d", name, expected_args, argc);
+ orc_program_set_error (program, "not the correct number of arguments provided for opcode");
+ return -1;
+ }
+
+ if (argc != expected_args) {
+ ORC_ERROR ("not the correct number of arguments provided for opcode: %s expects %d but got %d", name, expected_args, argc);
+ };
+
+ for (i=0;i<expected_args;i++){
+ args[i] = orc_program_find_var_by_name (program, argv[i]);
+ if (args[i] == -1) {
+ ORC_ERROR ("bad operand \"%s\" in position %d for opcode: %s at line %d",
+ argv[i], i+1, name, insn->line);
+ orc_program_set_error (program, "bad operand");
+ return i+1;
+ }
}
- args[0] = orc_program_find_var_by_name (program, arg1);
- args[1] = orc_program_find_var_by_name (program, arg2);
- args[2] = orc_program_find_var_by_name (program, arg3);
- args[3] = orc_program_find_var_by_name (program, arg4);
insn->flags = flags;
+
i = 0;
insn->dest_args[0] = args[i++];
- if (insn->opcode->dest_size[1] != 0) {
+ if (insn->opcode->dest_size[1] != 0)
insn->dest_args[1] = args[i++];
- }
- if (insn->opcode->src_size[0] != 0) {
+ if (insn->opcode->src_size[0] != 0)
insn->src_args[0] = args[i++];
- }
- if (insn->opcode->src_size[1] != 0) {
+ if (insn->opcode->src_size[1] != 0)
insn->src_args[1] = args[i++];
- }
- if (insn->opcode->src_size[2] != 0) {
+ if (insn->opcode->src_size[2] != 0)
insn->src_args[2] = args[i++];
- }
+ if (insn->opcode->src_size[3] != 0)
+ insn->src_args[3] = args[i++];
+
program->n_insns++;
+ return 0;
}
/**
diff --git a/orc/orcprogram.h b/orc/orcprogram.h
index 51123e4..e55ed44 100644
--- a/orc/orcprogram.h
+++ b/orc/orcprogram.h
@@ -132,6 +132,8 @@ ORC_API void orc_program_append_str (OrcProgram *p, const char *opcode,
ORC_API void orc_program_append_str_2 (OrcProgram *program, const char *name,
unsigned int flags, const char *arg1, const char *arg2, const char *arg3,
const char *arg4);
+ORC_API int orc_program_append_str_n (OrcProgram *program, const char *name,
+ unsigned int flags, int argc, const char **argv);
ORC_API void orc_program_append_ds (OrcProgram *program, const char *opcode, int arg0,
int arg1);
ORC_API void orc_program_append_ds_str (OrcProgram *p, const char *opcode,