mirror of
https://github.com/alsa-project/alsa-lib.git
synced 2025-10-29 05:40:25 -04:00
ALISP update
- function names are more emacs-like - implemented (format) function - fixed numerous memory-leaks (valgrind is now happy) Ordinary mixer - added the global view (using hdsp names only)
This commit is contained in:
parent
beb837bcf7
commit
d0facfde2b
10 changed files with 628 additions and 250 deletions
|
|
@ -3,7 +3,7 @@
|
||||||
; The test is indended to find memory leaks.
|
; The test is indended to find memory leaks.
|
||||||
;
|
;
|
||||||
; Copyright (c) 2003 Jaroslav Kysela <perex@suse.cz>
|
; Copyright (c) 2003 Jaroslav Kysela <perex@suse.cz>
|
||||||
; License: GPL
|
; License: GPL v2 (http://www.gnu.org/licenses/gpl.html)
|
||||||
;
|
;
|
||||||
|
|
||||||
;
|
;
|
||||||
|
|
@ -120,7 +120,7 @@
|
||||||
(atom "one") (&check-memory)
|
(atom "one") (&check-memory)
|
||||||
(atom "one" 'two) (&check-memory)
|
(atom "one" 'two) (&check-memory)
|
||||||
|
|
||||||
(call) (&check-memory)
|
(funcall) (&check-memory)
|
||||||
|
|
||||||
(car) (&check-memory)
|
(car) (&check-memory)
|
||||||
(car '(one . two)) (&check-memory)
|
(car '(one . two)) (&check-memory)
|
||||||
|
|
@ -128,6 +128,13 @@
|
||||||
(cdr) (&check-memory)
|
(cdr) (&check-memory)
|
||||||
(cdr '(one . two)) (&check-memory)
|
(cdr '(one . two)) (&check-memory)
|
||||||
|
|
||||||
|
(concat) (&check-memory)
|
||||||
|
(concat 'aaaa) (&check-memory)
|
||||||
|
(concat 'aaaa 'bbbb) (&check-memory)
|
||||||
|
(concat "aaaa") (&check-memory)
|
||||||
|
(concat "aaaa" "bbbb") (&check-memory)
|
||||||
|
(concat "aaaa" "bbbb" "cccc") (&check-memory)
|
||||||
|
|
||||||
(cond) (&check-memory)
|
(cond) (&check-memory)
|
||||||
(cond 0) (&check-memory)
|
(cond 0) (&check-memory)
|
||||||
(cond 0 1) (&check-memory)
|
(cond 0 1) (&check-memory)
|
||||||
|
|
@ -160,11 +167,17 @@
|
||||||
(exfun 'abcd) (&check-memory)
|
(exfun 'abcd) (&check-memory)
|
||||||
(exfun 'abcd 'ijkl) (&check-memory)
|
(exfun 'abcd 'ijkl) (&check-memory)
|
||||||
|
|
||||||
(float) (&check-memory)
|
(format) (&check-memory)
|
||||||
(float 1) (&check-memory)
|
(format 1) (&check-memory)
|
||||||
(float 'a) (&check-memory)
|
(format 'a) (&check-memory)
|
||||||
(float "a" "b" "c") (&check-memory)
|
(format "a" "b" "c") (&check-memory)
|
||||||
(float "1.2") (&check-memory)
|
(format "1.2") (&check-memory)
|
||||||
|
(format "%c" 43) (&check-memory)
|
||||||
|
(format "%d" 12) (&check-memory)
|
||||||
|
(format "%i" 12) (&check-memory)
|
||||||
|
(format "%f" 12.1) (&check-memory)
|
||||||
|
(format "%s" "abcd") (&check-memory)
|
||||||
|
(format "%s %i %i" "abcd" 1 2) (&check-memory)
|
||||||
|
|
||||||
(garbage-collect) (&check-memory)
|
(garbage-collect) (&check-memory)
|
||||||
(gc) (&check-memory)
|
(gc) (&check-memory)
|
||||||
|
|
@ -179,12 +192,6 @@
|
||||||
|
|
||||||
(include "itest.lisp") (&check-memory)
|
(include "itest.lisp") (&check-memory)
|
||||||
|
|
||||||
(int) (&check-memory)
|
|
||||||
(int 1) (&check-memory)
|
|
||||||
(int 'a) (&check-memory)
|
|
||||||
(int "a" "b" "c") (&check-memory)
|
|
||||||
(int "1.2") (&check-memory)
|
|
||||||
|
|
||||||
(list) (&check-memory)
|
(list) (&check-memory)
|
||||||
(list "a") (&check-memory)
|
(list "a") (&check-memory)
|
||||||
(list "a" "b") (&check-memory)
|
(list "a" "b") (&check-memory)
|
||||||
|
|
@ -267,10 +274,28 @@
|
||||||
(setq a 1) (unsetq a) (&check-memory)
|
(setq a 1) (unsetq a) (&check-memory)
|
||||||
(setq a 1 2) (unsetq a) (&check-memory)
|
(setq a 1 2) (unsetq a) (&check-memory)
|
||||||
|
|
||||||
(str) (&check-memory)
|
(string-equal) (&check-memory)
|
||||||
(str 1) (&check-memory)
|
(string-equal 1) (&check-memory)
|
||||||
(str 1 2 3) (&check-memory)
|
(string-equal "a") (&check-memory)
|
||||||
(str 1.2 1.3) (&check-memory)
|
(string-equal "a" "a") (&check-memory)
|
||||||
|
(string-equal "a" "b") (&check-memory)
|
||||||
|
(string-equal "a" "b" "c") (&check-memory)
|
||||||
|
|
||||||
|
(string-to-integer) (&check-memory)
|
||||||
|
(string-to-integer 1) (&check-memory)
|
||||||
|
(string-to-integer 1.5) (&check-memory)
|
||||||
|
(string-to-integer "a") (&check-memory)
|
||||||
|
(string-to-integer "a" "a") (&check-memory)
|
||||||
|
(string-to-integer "a" "b") (&check-memory)
|
||||||
|
(string-to-integer "a" "b" "c") (&check-memory)
|
||||||
|
|
||||||
|
(string-to-float) (&check-memory)
|
||||||
|
(string-to-float 1) (&check-memory)
|
||||||
|
(string-to-float 1.5) (&check-memory)
|
||||||
|
(string-to-float "a") (&check-memory)
|
||||||
|
(string-to-float "a" "a") (&check-memory)
|
||||||
|
(string-to-float "a" "b") (&check-memory)
|
||||||
|
(string-to-float "a" "b" "c") (&check-memory)
|
||||||
|
|
||||||
(string=) (&check-memory)
|
(string=) (&check-memory)
|
||||||
(string= 1) (&check-memory)
|
(string= 1) (&check-memory)
|
||||||
|
|
@ -279,13 +304,6 @@
|
||||||
(string= "a" "b") (&check-memory)
|
(string= "a" "b") (&check-memory)
|
||||||
(string= "a" "b" "c") (&check-memory)
|
(string= "a" "b" "c") (&check-memory)
|
||||||
|
|
||||||
(string-equal) (&check-memory)
|
|
||||||
(string-equal 1) (&check-memory)
|
|
||||||
(string-equal "a") (&check-memory)
|
|
||||||
(string-equal "a" "a") (&check-memory)
|
|
||||||
(string-equal "a" "b") (&check-memory)
|
|
||||||
(string-equal "a" "b" "c") (&check-memory)
|
|
||||||
|
|
||||||
(unless) (&check-memory)
|
(unless) (&check-memory)
|
||||||
(unless 1) (&check-memory)
|
(unless 1) (&check-memory)
|
||||||
(unless 0 1 2) (&check-memory)
|
(unless 0 1 2) (&check-memory)
|
||||||
|
|
@ -322,27 +340,31 @@
|
||||||
(unsetq abcd)
|
(unsetq abcd)
|
||||||
(&check-memory)
|
(&check-memory)
|
||||||
|
|
||||||
|
(setq abcd (("abcd" . "efgh") ("1234" . "5678")))
|
||||||
|
(unsetq abcd)
|
||||||
|
(&check-memory)
|
||||||
|
|
||||||
(defun myfun () (princ "a\n"))
|
(defun myfun () (princ "a\n"))
|
||||||
(exfun 'myfun)
|
(exfun 'myfun)
|
||||||
(unsetq myfun)
|
(unsetq myfun)
|
||||||
(&check-memory)
|
(&check-memory)
|
||||||
|
|
||||||
(defun myfun () (princ "a\n"))
|
(defun myfun () (princ "a\n"))
|
||||||
(call 'myfun)
|
(funcall 'myfun)
|
||||||
(call 'myfun 'aaaaa)
|
(funcall 'myfun 'aaaaa)
|
||||||
(unsetq myfun)
|
(unsetq myfun)
|
||||||
(&check-memory)
|
(&check-memory)
|
||||||
|
|
||||||
(defun myfun (o) (princ o "a\n"))
|
(defun myfun (o) (princ o "a\n"))
|
||||||
(call 'myfun)
|
(funcall 'myfun)
|
||||||
(call 'myfun 'aaaaa)
|
(funcall 'myfun 'aaaaa)
|
||||||
(unsetq myfun)
|
(unsetq myfun)
|
||||||
(&check-memory)
|
(&check-memory)
|
||||||
|
|
||||||
(defun myfun (o p) (princ o p "\n"))
|
(defun myfun (o p) (princ o p "\n"))
|
||||||
(call 'myfun)
|
(funcall 'myfun)
|
||||||
(call 'myfun 'aaaaa)
|
(funcall 'myfun 'aaaaa)
|
||||||
(call 'myfun 'aaaaa 'bbbbb)
|
(funcall 'myfun 'aaaaa 'bbbbb)
|
||||||
(unsetq myfun)
|
(unsetq myfun)
|
||||||
(&check-memory)
|
(&check-memory)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,8 @@ int alsa_lisp_function(struct alisp_instance *instance, struct alisp_seq_iterato
|
||||||
__attribute__ ((format (printf, 4, 5)))
|
__attribute__ ((format (printf, 4, 5)))
|
||||||
#endif
|
#endif
|
||||||
;
|
;
|
||||||
|
void alsa_lisp_result_free(struct alisp_instance *instance,
|
||||||
|
struct alisp_seq_iterator *result);
|
||||||
int alsa_lisp_seq_first(struct alisp_instance *instance, const char *id,
|
int alsa_lisp_seq_first(struct alisp_instance *instance, const char *id,
|
||||||
struct alisp_seq_iterator **seq);
|
struct alisp_seq_iterator **seq);
|
||||||
int alsa_lisp_seq_next(struct alisp_seq_iterator **seq);
|
int alsa_lisp_seq_next(struct alisp_seq_iterator **seq);
|
||||||
|
|
|
||||||
|
|
@ -195,7 +195,8 @@ extern "C" {
|
||||||
* \{
|
* \{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int sndo_mixer_open(sndo_mixer_t **pmixer, snd_pcm_t *playback_pcm, snd_pcm_t *capture_pcm, struct alisp_cfg *lconf);
|
int sndo_mixer_open(sndo_mixer_t **pmixer, const char *playback_name, const char *capture_name, struct alisp_cfg *lconf);
|
||||||
|
int sndo_mixer_open_pcm(sndo_mixer_t **pmixer, snd_pcm_t *playback_pcm, snd_pcm_t *capture_pcm, struct alisp_cfg *lconf);
|
||||||
int sndo_mixer_close(sndo_mixer_t *mixer);
|
int sndo_mixer_close(sndo_mixer_t *mixer);
|
||||||
int sndo_mixer_poll_descriptors_count(sndo_mixer_t *mixer);
|
int sndo_mixer_poll_descriptors_count(sndo_mixer_t *mixer);
|
||||||
int sndo_mixer_poll_descriptors(sndo_mixer_t *mixer, struct pollfd *pfds, unsigned int space);
|
int sndo_mixer_poll_descriptors(sndo_mixer_t *mixer, struct pollfd *pfds, unsigned int space);
|
||||||
|
|
|
||||||
|
|
@ -46,11 +46,11 @@ static struct alisp_object * parse_object(struct alisp_instance *instance, int h
|
||||||
static void princ_cons(snd_output_t *out, struct alisp_object * p);
|
static void princ_cons(snd_output_t *out, struct alisp_object * p);
|
||||||
static void princ_object(snd_output_t *out, struct alisp_object * p);
|
static void princ_object(snd_output_t *out, struct alisp_object * p);
|
||||||
static struct alisp_object * eval(struct alisp_instance *instance, struct alisp_object * p);
|
static struct alisp_object * eval(struct alisp_instance *instance, struct alisp_object * p);
|
||||||
static struct alisp_object * eval_cons1(struct alisp_instance *instance, struct alisp_object * p1, struct alisp_object * p2);
|
|
||||||
|
|
||||||
/* functions */
|
/* functions */
|
||||||
static struct alisp_object *F_eval(struct alisp_instance *instance, struct alisp_object *);
|
static struct alisp_object *F_eval(struct alisp_instance *instance, struct alisp_object *);
|
||||||
static struct alisp_object *F_progn(struct alisp_instance *instance, struct alisp_object *);
|
static struct alisp_object *F_progn(struct alisp_instance *instance, struct alisp_object *);
|
||||||
|
static struct alisp_object *F_funcall(struct alisp_instance *instance, struct alisp_object *);
|
||||||
|
|
||||||
/* others */
|
/* others */
|
||||||
static int alisp_include_file(struct alisp_instance *instance, const char *filename);
|
static int alisp_include_file(struct alisp_instance *instance, const char *filename);
|
||||||
|
|
@ -176,9 +176,7 @@ static void free_object(struct alisp_object * p)
|
||||||
|
|
||||||
static void delete_object(struct alisp_instance *instance, struct alisp_object * p)
|
static void delete_object(struct alisp_instance *instance, struct alisp_object * p)
|
||||||
{
|
{
|
||||||
if (p == NULL)
|
if (p == NULL || p == &alsa_lisp_nil || p == &alsa_lisp_t)
|
||||||
return;
|
|
||||||
if (p == &alsa_lisp_nil || p == &alsa_lisp_t)
|
|
||||||
return;
|
return;
|
||||||
if (alisp_compare_type(p, ALISP_OBJ_NIL) ||
|
if (alisp_compare_type(p, ALISP_OBJ_NIL) ||
|
||||||
alisp_compare_type(p, ALISP_OBJ_T))
|
alisp_compare_type(p, ALISP_OBJ_T))
|
||||||
|
|
@ -215,8 +213,8 @@ static void delete_tree(struct alisp_instance *instance, struct alisp_object * p
|
||||||
|
|
||||||
static struct alisp_object * incref_object(struct alisp_instance *instance ATTRIBUTE_UNUSED, struct alisp_object * p)
|
static struct alisp_object * incref_object(struct alisp_instance *instance ATTRIBUTE_UNUSED, struct alisp_object * p)
|
||||||
{
|
{
|
||||||
if (p == NULL)
|
if (p == NULL || p == &alsa_lisp_nil || p == &alsa_lisp_t)
|
||||||
return NULL;
|
return p;
|
||||||
if (alisp_get_refs(p) == ALISP_MAX_REFS) {
|
if (alisp_get_refs(p) == ALISP_MAX_REFS) {
|
||||||
assert(0);
|
assert(0);
|
||||||
fprintf(stderr, "OOPS: alsa lisp: incref fatal error\n");
|
fprintf(stderr, "OOPS: alsa lisp: incref fatal error\n");
|
||||||
|
|
@ -259,12 +257,30 @@ static void free_objects(struct alisp_instance *instance)
|
||||||
{
|
{
|
||||||
struct list_head *pos, *pos1;
|
struct list_head *pos, *pos1;
|
||||||
struct alisp_object * p;
|
struct alisp_object * p;
|
||||||
|
struct alisp_object_pair * pair;
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
|
for (i = 0; i < ALISP_OBJ_PAIR_HASH_SIZE; i++) {
|
||||||
|
list_for_each_safe(pos, pos1, &instance->setobjs_list[i]) {
|
||||||
|
pair = list_entry(pos, struct alisp_object_pair, list);
|
||||||
|
lisp_debug(instance, "freeing pair: '%s' -> %p", pair->name, pair->value);
|
||||||
|
delete_tree(instance, pair->value);
|
||||||
|
free((void *)pair->name);
|
||||||
|
free(pair);
|
||||||
|
}
|
||||||
|
}
|
||||||
for (i = 0; i < ALISP_OBJ_PAIR_HASH_SIZE; i++)
|
for (i = 0; i < ALISP_OBJ_PAIR_HASH_SIZE; i++)
|
||||||
for (j = 0; j <= ALISP_OBJ_LAST_SEARCH; j++) {
|
for (j = 0; j <= ALISP_OBJ_LAST_SEARCH; j++) {
|
||||||
list_for_each_safe(pos, pos1, &instance->used_objs_list[i][j]) {
|
list_for_each_safe(pos, pos1, &instance->used_objs_list[i][j]) {
|
||||||
p = list_entry(pos, struct alisp_object, list);
|
p = list_entry(pos, struct alisp_object, list);
|
||||||
|
lisp_warn(instance, "object %p is still referenced %i times!", p, alisp_get_refs(p));
|
||||||
|
#if 0
|
||||||
|
snd_output_printf(instance->wout, ">>>> ");
|
||||||
|
princ_object(instance->wout, p);
|
||||||
|
snd_output_printf(instance->wout, " <<<<\n");
|
||||||
|
#endif
|
||||||
|
if (alisp_get_refs(p) > 0)
|
||||||
|
alisp_set_refs(p, 1);
|
||||||
delete_object(instance, p);
|
delete_object(instance, p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -575,7 +591,7 @@ static int gettoken(struct alisp_instance *instance)
|
||||||
instance->thistoken = ALISP_INTEGER;
|
instance->thistoken = ALISP_INTEGER;
|
||||||
do {
|
do {
|
||||||
__ok:
|
__ok:
|
||||||
if (p - instance->token_buffer >= instance->token_buffer_max) {
|
if (p - instance->token_buffer >= instance->token_buffer_max - 1) {
|
||||||
p = extend_buf(instance, p);
|
p = extend_buf(instance, p);
|
||||||
if (p == NULL)
|
if (p == NULL)
|
||||||
return instance->thistoken = EOF;
|
return instance->thistoken = EOF;
|
||||||
|
|
@ -620,7 +636,7 @@ static int gettoken(struct alisp_instance *instance)
|
||||||
/* Identifier: [!-/+*%<>=&a-zA-Z_][-/+*%<>=&a-zA-Z_0-9]* */
|
/* Identifier: [!-/+*%<>=&a-zA-Z_][-/+*%<>=&a-zA-Z_0-9]* */
|
||||||
p = instance->token_buffer;
|
p = instance->token_buffer;
|
||||||
do {
|
do {
|
||||||
if (p - instance->token_buffer >= instance->token_buffer_max) {
|
if (p - instance->token_buffer >= instance->token_buffer_max - 1) {
|
||||||
p = extend_buf(instance, p);
|
p = extend_buf(instance, p);
|
||||||
if (p == NULL)
|
if (p == NULL)
|
||||||
return instance->thistoken = EOF;
|
return instance->thistoken = EOF;
|
||||||
|
|
@ -636,7 +652,7 @@ static int gettoken(struct alisp_instance *instance)
|
||||||
/* String: "\""([^"]|"\\".)*"\"" */
|
/* String: "\""([^"]|"\\".)*"\"" */
|
||||||
p = instance->token_buffer;
|
p = instance->token_buffer;
|
||||||
while ((c = xgetc(instance)) != '"' && c != EOF) {
|
while ((c = xgetc(instance)) != '"' && c != EOF) {
|
||||||
if (p - instance->token_buffer >= instance->token_buffer_max) {
|
if (p - instance->token_buffer >= instance->token_buffer_max - 1) {
|
||||||
p = extend_buf(instance, p);
|
p = extend_buf(instance, p);
|
||||||
if (p == NULL)
|
if (p == NULL)
|
||||||
return instance->thistoken = EOF;
|
return instance->thistoken = EOF;
|
||||||
|
|
@ -683,24 +699,26 @@ static struct alisp_object * parse_form(struct alisp_instance *instance)
|
||||||
* Parse a dotted pair notation.
|
* Parse a dotted pair notation.
|
||||||
*/
|
*/
|
||||||
if (thistoken == '.') {
|
if (thistoken == '.') {
|
||||||
thistoken = gettoken(instance);
|
gettoken(instance);
|
||||||
if (prev == NULL) {
|
if (prev == NULL) {
|
||||||
lisp_error(instance, "unexpected `.'");
|
lisp_error(instance, "unexpected '.'");
|
||||||
|
__err:
|
||||||
|
delete_tree(instance, first);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
prev->value.c.cdr = parse_object(instance, 1);
|
prev->value.c.cdr = parse_object(instance, 1);
|
||||||
if (prev->value.c.cdr == NULL)
|
if (prev->value.c.cdr == NULL)
|
||||||
return NULL;
|
goto __err;
|
||||||
if ((thistoken = gettoken(instance)) != ')') {
|
if ((thistoken = gettoken(instance)) != ')') {
|
||||||
lisp_error(instance, "expected `)'");
|
lisp_error(instance, "expected ')'");
|
||||||
return NULL;
|
goto __err;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
p = new_object(instance, ALISP_OBJ_CONS);
|
p = new_object(instance, ALISP_OBJ_CONS);
|
||||||
if (p == NULL)
|
if (p == NULL)
|
||||||
return NULL;
|
goto __err;
|
||||||
|
|
||||||
if (first == NULL)
|
if (first == NULL)
|
||||||
first = p;
|
first = p;
|
||||||
|
|
@ -709,7 +727,8 @@ static struct alisp_object * parse_form(struct alisp_instance *instance)
|
||||||
|
|
||||||
p->value.c.car = parse_object(instance, 1);
|
p->value.c.car = parse_object(instance, 1);
|
||||||
if (p->value.c.car == NULL)
|
if (p->value.c.car == NULL)
|
||||||
return NULL;
|
goto __err;
|
||||||
|
|
||||||
prev = p;
|
prev = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -724,11 +743,11 @@ static struct alisp_object * quote_object(struct alisp_instance *instance, struc
|
||||||
struct alisp_object * p;
|
struct alisp_object * p;
|
||||||
|
|
||||||
if (obj == NULL)
|
if (obj == NULL)
|
||||||
return NULL;
|
goto __end1;
|
||||||
|
|
||||||
p = new_object(instance, ALISP_OBJ_CONS);
|
p = new_object(instance, ALISP_OBJ_CONS);
|
||||||
if (p == NULL)
|
if (p == NULL)
|
||||||
return NULL;
|
goto __end1;
|
||||||
|
|
||||||
p->value.c.car = new_identifier(instance, "quote");
|
p->value.c.car = new_identifier(instance, "quote");
|
||||||
if (p->value.c.car == NULL)
|
if (p->value.c.car == NULL)
|
||||||
|
|
@ -737,8 +756,9 @@ static struct alisp_object * quote_object(struct alisp_instance *instance, struc
|
||||||
if (p->value.c.cdr == NULL) {
|
if (p->value.c.cdr == NULL) {
|
||||||
delete_object(instance, p->value.c.car);
|
delete_object(instance, p->value.c.car);
|
||||||
__end:
|
__end:
|
||||||
delete_object(instance, obj);
|
|
||||||
delete_object(instance, p);
|
delete_object(instance, p);
|
||||||
|
__end1:
|
||||||
|
delete_tree(instance, obj);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -898,6 +918,7 @@ static struct alisp_object * unset_object(struct alisp_instance *instance, struc
|
||||||
if (!strcmp(p->name, id)) {
|
if (!strcmp(p->name, id)) {
|
||||||
list_del(&p->list);
|
list_del(&p->list);
|
||||||
res = p->value;
|
res = p->value;
|
||||||
|
free((void *)p->name);
|
||||||
free(p);
|
free(p);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
@ -1117,74 +1138,78 @@ static struct alisp_object * F_cdr(struct alisp_instance *instance, struct alisp
|
||||||
static struct alisp_object * F_add(struct alisp_instance *instance, struct alisp_object * args)
|
static struct alisp_object * F_add(struct alisp_instance *instance, struct alisp_object * args)
|
||||||
{
|
{
|
||||||
struct alisp_object * p = args, * p1, * n;
|
struct alisp_object * p = args, * p1, * n;
|
||||||
|
long v = 0;
|
||||||
|
double f = 0;
|
||||||
|
int type = ALISP_OBJ_INTEGER;
|
||||||
|
|
||||||
p1 = eval(instance, car(p));
|
p1 = eval(instance, car(p));
|
||||||
if (alisp_compare_type(p1, ALISP_OBJ_INTEGER) ||
|
for (;;) {
|
||||||
alisp_compare_type(p1, ALISP_OBJ_FLOAT)) {
|
if (alisp_compare_type(p1, ALISP_OBJ_INTEGER)) {
|
||||||
long v = 0;
|
if (type == ALISP_OBJ_FLOAT)
|
||||||
double f = 0;
|
f += p1->value.i;
|
||||||
int type = ALISP_OBJ_INTEGER;
|
else
|
||||||
for (;;) {
|
v += p1->value.i;
|
||||||
if (alisp_compare_type(p1, ALISP_OBJ_INTEGER)) {
|
} else if (alisp_compare_type(p1, ALISP_OBJ_FLOAT)) {
|
||||||
if (type == ALISP_OBJ_FLOAT)
|
f += p1->value.f + v;
|
||||||
f += p1->value.i;
|
v = 0;
|
||||||
else
|
type = ALISP_OBJ_FLOAT;
|
||||||
v += p1->value.i;
|
|
||||||
} else if (alisp_compare_type(p1, ALISP_OBJ_FLOAT)) {
|
|
||||||
f += p1->value.f + v;
|
|
||||||
v = 0;
|
|
||||||
type = ALISP_OBJ_FLOAT;
|
|
||||||
} else {
|
|
||||||
lisp_warn(instance, "sum with a non integer or float operand");
|
|
||||||
}
|
|
||||||
delete_tree(instance, p1);
|
|
||||||
p = cdr(n = p);
|
|
||||||
delete_object(instance, n);
|
|
||||||
if (p == &alsa_lisp_nil)
|
|
||||||
break;
|
|
||||||
p1 = eval(instance, car(p));
|
|
||||||
}
|
|
||||||
if (type == ALISP_OBJ_INTEGER) {
|
|
||||||
return new_integer(instance, v);
|
|
||||||
} else {
|
} else {
|
||||||
return new_float(instance, f);
|
lisp_warn(instance, "sum with a non integer or float operand");
|
||||||
}
|
}
|
||||||
} else if (alisp_compare_type(p1, ALISP_OBJ_STRING)) {
|
delete_tree(instance, p1);
|
||||||
char *str = NULL, *str1;
|
p = cdr(n = p);
|
||||||
for (;;) {
|
delete_object(instance, n);
|
||||||
if (alisp_compare_type(p1, ALISP_OBJ_STRING)) {
|
if (p == &alsa_lisp_nil)
|
||||||
str1 = realloc(str, (str ? strlen(str) : 0) + strlen(p1->value.s) + 1);
|
break;
|
||||||
if (str1 == NULL) {
|
p1 = eval(instance, car(p));
|
||||||
nomem();
|
}
|
||||||
if (str)
|
if (type == ALISP_OBJ_INTEGER) {
|
||||||
free(str);
|
return new_integer(instance, v);
|
||||||
return NULL;
|
} else {
|
||||||
}
|
return new_float(instance, f);
|
||||||
if (str == NULL)
|
}
|
||||||
strcpy(str1, p1->value.s);
|
}
|
||||||
else
|
|
||||||
strcat(str1, p1->value.s);
|
/*
|
||||||
str = str1;
|
* Syntax: (concat expr...)
|
||||||
} else {
|
*/
|
||||||
lisp_warn(instance, "concat with a non string or identifier operand");
|
static struct alisp_object * F_concat(struct alisp_instance *instance, struct alisp_object * args)
|
||||||
|
{
|
||||||
|
struct alisp_object * p = args, * p1, * n;
|
||||||
|
char *str = NULL, *str1;
|
||||||
|
|
||||||
|
p1 = eval(instance, car(p));
|
||||||
|
for (;;) {
|
||||||
|
if (alisp_compare_type(p1, ALISP_OBJ_STRING)) {
|
||||||
|
str1 = realloc(str, (str ? strlen(str) : 0) + strlen(p1->value.s) + 1);
|
||||||
|
if (str1 == NULL) {
|
||||||
|
nomem();
|
||||||
|
if (str)
|
||||||
|
free(str);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
delete_tree(instance, p1);
|
if (str == NULL)
|
||||||
p = cdr(n = p);
|
strcpy(str1, p1->value.s);
|
||||||
delete_object(instance, n);
|
else
|
||||||
if (p == &alsa_lisp_nil)
|
strcat(str1, p1->value.s);
|
||||||
break;
|
str = str1;
|
||||||
p1 = eval(instance, car(p));
|
} else {
|
||||||
|
lisp_warn(instance, "concat with a non string or identifier operand");
|
||||||
}
|
}
|
||||||
|
delete_tree(instance, p1);
|
||||||
|
p = cdr(n = p);
|
||||||
|
delete_object(instance, n);
|
||||||
|
if (p == &alsa_lisp_nil)
|
||||||
|
break;
|
||||||
|
p1 = eval(instance, car(p));
|
||||||
|
}
|
||||||
|
if (str) {
|
||||||
p = new_string(instance, str);
|
p = new_string(instance, str);
|
||||||
free(str);
|
free(str);
|
||||||
return p;
|
|
||||||
} else {
|
} else {
|
||||||
lisp_warn(instance, "sum/concat with non-integer or string operand");
|
p = &alsa_lisp_nil;
|
||||||
delete_tree(instance, cdr(p));
|
|
||||||
delete_object(instance, p);
|
|
||||||
delete_tree(instance, p1);
|
|
||||||
}
|
}
|
||||||
return &alsa_lisp_nil;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -2218,6 +2243,7 @@ static struct alisp_object * F_unsetq(struct alisp_instance *instance, struct al
|
||||||
if (p1)
|
if (p1)
|
||||||
delete_tree(instance, p1);
|
delete_tree(instance, p1);
|
||||||
p1 = unset_object(instance, car(p));
|
p1 = unset_object(instance, car(p));
|
||||||
|
delete_tree(instance, car(p));
|
||||||
p = cdr(n = p);
|
p = cdr(n = p);
|
||||||
delete_object(instance, n);
|
delete_object(instance, n);
|
||||||
} while (p != &alsa_lisp_nil);
|
} while (p != &alsa_lisp_nil);
|
||||||
|
|
@ -2269,7 +2295,7 @@ static struct alisp_object * F_defun(struct alisp_instance *instance, struct ali
|
||||||
|
|
||||||
static struct alisp_object * eval_func(struct alisp_instance *instance, struct alisp_object * p, struct alisp_object * args)
|
static struct alisp_object * eval_func(struct alisp_instance *instance, struct alisp_object * p, struct alisp_object * args)
|
||||||
{
|
{
|
||||||
struct alisp_object * p1, * p2, * p3, * p4, * p5;
|
struct alisp_object * p1, * p2, * p3, * p4;
|
||||||
struct alisp_object ** eval_objs, ** save_objs;
|
struct alisp_object ** eval_objs, ** save_objs;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
|
@ -2297,9 +2323,8 @@ static struct alisp_object * eval_func(struct alisp_instance *instance, struct a
|
||||||
i = 0;
|
i = 0;
|
||||||
while (p3 != &alsa_lisp_nil) {
|
while (p3 != &alsa_lisp_nil) {
|
||||||
eval_objs[i++] = eval(instance, car(p3));
|
eval_objs[i++] = eval(instance, car(p3));
|
||||||
p4 = cdr(p3);
|
p3 = cdr(p4 = p3);
|
||||||
delete_object(instance, p3);
|
delete_object(instance, p4);
|
||||||
p3 = p4;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -2307,48 +2332,49 @@ static struct alisp_object * eval_func(struct alisp_instance *instance, struct a
|
||||||
*/
|
*/
|
||||||
i = 0;
|
i = 0;
|
||||||
while (p2 != &alsa_lisp_nil) {
|
while (p2 != &alsa_lisp_nil) {
|
||||||
p4 = car(p2);
|
p3 = car(p2);
|
||||||
save_objs[i] = replace_object(instance, p4, eval_objs[i]);
|
save_objs[i] = replace_object(instance, p3, eval_objs[i]);
|
||||||
if (save_objs[i] == NULL &&
|
if (save_objs[i] == NULL &&
|
||||||
set_object_direct(instance, p4, eval_objs[i]) == NULL)
|
set_object_direct(instance, p3, eval_objs[i]) == NULL) {
|
||||||
|
p4 = NULL;
|
||||||
goto _end;
|
goto _end;
|
||||||
|
}
|
||||||
p2 = cdr(p2);
|
p2 = cdr(p2);
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
|
|
||||||
p5 = F_progn(instance, incref_tree(instance, cdr(cdr(p))));
|
p4 = F_progn(instance, cdr(incref_tree(instance, p3 = cdr(p))));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Restore the old variable values.
|
* Restore the old variable values.
|
||||||
*/
|
*/
|
||||||
p2 = car(cdr(p));
|
p2 = car(p3);
|
||||||
|
delete_object(instance, p3);
|
||||||
i = 0;
|
i = 0;
|
||||||
while (p2 != &alsa_lisp_nil) {
|
while (p2 != &alsa_lisp_nil) {
|
||||||
p4 = car(p2);
|
p3 = car(p2);
|
||||||
if (save_objs[i] == NULL) {
|
if (save_objs[i] == NULL) {
|
||||||
p4 = unset_object(instance, p4);
|
p3 = unset_object(instance, p3);
|
||||||
} else {
|
} else {
|
||||||
p4 = replace_object(instance, p4, save_objs[i]);
|
p3 = replace_object(instance, p3, save_objs[i]);
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
delete_tree(instance, p4);
|
delete_tree(instance, p3);
|
||||||
p2 = cdr(p2);
|
delete_tree(instance, car(p2));
|
||||||
|
p2 = cdr(p3 = p2);
|
||||||
|
delete_object(instance, p3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_end:
|
||||||
if (eval_objs)
|
if (eval_objs)
|
||||||
free(eval_objs);
|
free(eval_objs);
|
||||||
|
|
||||||
return p5;
|
return p4;
|
||||||
} else {
|
} else {
|
||||||
_delete:
|
_delete:
|
||||||
delete_tree(instance, args);
|
delete_tree(instance, args);
|
||||||
}
|
}
|
||||||
return &alsa_lisp_nil;
|
return &alsa_lisp_nil;
|
||||||
|
|
||||||
_end:
|
|
||||||
if (eval_objs)
|
|
||||||
free(eval_objs);
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct alisp_object * F_gc(struct alisp_instance *instance ATTRIBUTE_UNUSED, struct alisp_object * args ATTRIBUTE_UNUSED)
|
struct alisp_object * F_gc(struct alisp_instance *instance ATTRIBUTE_UNUSED, struct alisp_object * args ATTRIBUTE_UNUSED)
|
||||||
|
|
@ -2401,30 +2427,10 @@ struct alisp_object * F_include(struct alisp_instance *instance, struct alisp_ob
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Syntax: (call function args...)
|
* Syntax: (string-to-integer value)
|
||||||
*/
|
|
||||||
struct alisp_object * F_call(struct alisp_instance *instance, struct alisp_object * args)
|
|
||||||
{
|
|
||||||
struct alisp_object * p = eval(instance, car(args)), * p1;
|
|
||||||
|
|
||||||
if (!alisp_compare_type(p, ALISP_OBJ_IDENTIFIER) &&
|
|
||||||
!alisp_compare_type(p, ALISP_OBJ_STRING)) {
|
|
||||||
lisp_warn(instance, "expected an function name");
|
|
||||||
delete_tree(instance, p);
|
|
||||||
delete_tree(instance, cdr(args));
|
|
||||||
delete_object(instance, args);
|
|
||||||
return &alsa_lisp_nil;
|
|
||||||
}
|
|
||||||
p1 = cdr(args);
|
|
||||||
delete_object(instance, args);
|
|
||||||
return eval_cons1(instance, p, p1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Syntax: (int value)
|
|
||||||
* 'value' can be integer or float type
|
* 'value' can be integer or float type
|
||||||
*/
|
*/
|
||||||
struct alisp_object * F_int(struct alisp_instance *instance, struct alisp_object * args)
|
struct alisp_object * F_string_to_integer(struct alisp_instance *instance, struct alisp_object * args)
|
||||||
{
|
{
|
||||||
struct alisp_object * p = eval(instance, car(args)), * p1;
|
struct alisp_object * p = eval(instance, car(args)), * p1;
|
||||||
|
|
||||||
|
|
@ -2443,10 +2449,10 @@ struct alisp_object * F_int(struct alisp_instance *instance, struct alisp_object
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Syntax: (float value)
|
* Syntax: (string-to-float value)
|
||||||
* 'value' can be integer or float type
|
* 'value' can be integer or float type
|
||||||
*/
|
*/
|
||||||
struct alisp_object * F_float(struct alisp_instance *instance, struct alisp_object * args)
|
struct alisp_object * F_string_to_float(struct alisp_instance *instance, struct alisp_object * args)
|
||||||
{
|
{
|
||||||
struct alisp_object * p = eval(instance, car(args)), * p1;
|
struct alisp_object * p = eval(instance, car(args)), * p1;
|
||||||
|
|
||||||
|
|
@ -2464,41 +2470,281 @@ struct alisp_object * F_float(struct alisp_instance *instance, struct alisp_obje
|
||||||
return p1;
|
return p1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
static int append_to_string(char **s, int *len, char *from, int size)
|
||||||
* Syntax: (str value)
|
|
||||||
* 'value' can be integer, float or string type
|
|
||||||
*/
|
|
||||||
struct alisp_object * F_str(struct alisp_instance *instance, struct alisp_object * args)
|
|
||||||
{
|
{
|
||||||
struct alisp_object * p = eval(instance, car(args)), * p1;
|
if (*len == 0) {
|
||||||
|
*s = malloc(*len = size + 1);
|
||||||
delete_tree(instance, cdr(args));
|
if (*s == NULL) {
|
||||||
delete_object(instance, args);
|
|
||||||
if (alisp_compare_type(p, ALISP_OBJ_STRING))
|
|
||||||
return p;
|
|
||||||
if (alisp_compare_type(p, ALISP_OBJ_INTEGER) ||
|
|
||||||
alisp_compare_type(p, ALISP_OBJ_FLOAT)) {
|
|
||||||
char *buf = malloc(64);
|
|
||||||
if (buf == NULL) {
|
|
||||||
delete_tree(instance, p);
|
|
||||||
nomem();
|
nomem();
|
||||||
return NULL;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
if (alisp_compare_type(p, ALISP_OBJ_INTEGER)) {
|
memcpy(*s, from, size);
|
||||||
snprintf(buf, sizeof(buf), "%ld", p->value.i);
|
} else {
|
||||||
} else {
|
*len += size;
|
||||||
snprintf(buf, sizeof(buf), "%.f", p->value.f);
|
*s = realloc(*s, *len);
|
||||||
}
|
if (*s == NULL) {
|
||||||
p1 = new_string(instance, buf);
|
nomem();
|
||||||
free(buf);
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
memcpy(*s + strlen(*s), from, size);
|
||||||
|
}
|
||||||
|
(*s)[*len - 1] = '\0';
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int format_parse_char(struct alisp_instance *instance, char **s, int *len, struct alisp_object *p)
|
||||||
|
{
|
||||||
|
char b;
|
||||||
|
|
||||||
|
if (!alisp_compare_type(p, ALISP_OBJ_INTEGER)) {
|
||||||
|
lisp_warn(instance, "format: expected integer\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
b = p->value.i;
|
||||||
|
return append_to_string(s, len, &b, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int format_parse_integer(struct alisp_instance *instance, char **s, int *len, struct alisp_object *p)
|
||||||
|
{
|
||||||
|
int res;
|
||||||
|
char *s1;
|
||||||
|
|
||||||
|
if (!alisp_compare_type(p, ALISP_OBJ_INTEGER) &&
|
||||||
|
!alisp_compare_type(p, ALISP_OBJ_FLOAT)) {
|
||||||
|
lisp_warn(instance, "format: expected integer or float\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
s1 = malloc(64);
|
||||||
|
if (s1 == NULL) {
|
||||||
|
nomem();
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
sprintf(s1, "%li", alisp_compare_type(p, ALISP_OBJ_FLOAT) ? (long)floor(p->value.f) : p->value.i);
|
||||||
|
res = append_to_string(s, len, s1, strlen(s1));
|
||||||
|
free(s1);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int format_parse_float(struct alisp_instance *instance, char **s, int *len, struct alisp_object *p)
|
||||||
|
{
|
||||||
|
int res;
|
||||||
|
char *s1;
|
||||||
|
|
||||||
|
if (!alisp_compare_type(p, ALISP_OBJ_INTEGER) &&
|
||||||
|
!alisp_compare_type(p, ALISP_OBJ_FLOAT)) {
|
||||||
|
lisp_warn(instance, "format: expected integer or float\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
s1 = malloc(64);
|
||||||
|
if (s1 == NULL) {
|
||||||
|
nomem();
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
sprintf(s1, "%f", alisp_compare_type(p, ALISP_OBJ_FLOAT) ? p->value.f : (double)p->value.i);
|
||||||
|
res = append_to_string(s, len, s1, strlen(s1));
|
||||||
|
free(s1);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int format_parse_string(struct alisp_instance *instance, char **s, int *len, struct alisp_object *p)
|
||||||
|
{
|
||||||
|
if (!alisp_compare_type(p, ALISP_OBJ_STRING)) {
|
||||||
|
lisp_warn(instance, "format: expected string\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return append_to_string(s, len, p->value.s, strlen(p->value.s));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Syntax: (format format value...)
|
||||||
|
* 'format' is C-like format string
|
||||||
|
*/
|
||||||
|
struct alisp_object * F_format(struct alisp_instance *instance, struct alisp_object * args)
|
||||||
|
{
|
||||||
|
struct alisp_object * p = eval(instance, car(args)), * p1 = cdr(args), * n;
|
||||||
|
char *s, *s1, *s2;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
delete_object(instance, args);
|
||||||
|
if (!alisp_compare_type(p, ALISP_OBJ_STRING)) {
|
||||||
|
delete_tree(instance, p1);
|
||||||
|
delete_tree(instance, p);
|
||||||
|
lisp_warn(instance, "format: expected an format string");
|
||||||
|
return &alsa_lisp_nil;
|
||||||
|
}
|
||||||
|
s = p->value.s;
|
||||||
|
s1 = NULL;
|
||||||
|
len = 0;
|
||||||
|
n = eval(instance, car(p1));
|
||||||
|
do {
|
||||||
|
while (1) {
|
||||||
|
s2 = s;
|
||||||
|
while (*s2 && *s2 != '%')
|
||||||
|
s2++;
|
||||||
|
if (s2 != s) {
|
||||||
|
if (append_to_string(&s1, &len, s, s2 - s) < 0) {
|
||||||
|
__error:
|
||||||
|
delete_tree(instance, n);
|
||||||
|
delete_tree(instance, cdr(p1));
|
||||||
|
delete_object(instance, p1);
|
||||||
|
delete_tree(instance, p);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (*s2 == '%')
|
||||||
|
s2++;
|
||||||
|
switch (*s2) {
|
||||||
|
case '%':
|
||||||
|
if (append_to_string(&s1, &len, s2, 1) < 0)
|
||||||
|
goto __error;
|
||||||
|
s = s2 + 1;
|
||||||
|
break;
|
||||||
|
case 'c':
|
||||||
|
if (format_parse_char(instance, &s1, &len, n) < 0)
|
||||||
|
goto __error;
|
||||||
|
s = s2 + 1;
|
||||||
|
goto __next;
|
||||||
|
case 'd':
|
||||||
|
case 'i':
|
||||||
|
if (format_parse_integer(instance, &s1, &len, n) < 0)
|
||||||
|
goto __error;
|
||||||
|
s = s2 + 1;
|
||||||
|
goto __next;
|
||||||
|
case 'f':
|
||||||
|
if (format_parse_float(instance, &s1, &len, n) < 0)
|
||||||
|
goto __error;
|
||||||
|
s = s2 + 1;
|
||||||
|
goto __next;
|
||||||
|
case 's':
|
||||||
|
if (format_parse_string(instance, &s1, &len, n) < 0)
|
||||||
|
goto __error;
|
||||||
|
s = s2 + 1;
|
||||||
|
goto __next;
|
||||||
|
case '\0':
|
||||||
|
goto __end;
|
||||||
|
default:
|
||||||
|
lisp_warn(instance, "unknown format char '%c'", *s2);
|
||||||
|
s = s2 + 1;
|
||||||
|
goto __next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
__next:
|
||||||
|
delete_tree(instance, n);
|
||||||
|
p1 = cdr(n = p1);
|
||||||
|
delete_object(instance, n);
|
||||||
|
n = eval(instance, car(p1));
|
||||||
|
} while (*s);
|
||||||
|
__end:
|
||||||
|
delete_tree(instance, n);
|
||||||
|
delete_tree(instance, cdr(p1));
|
||||||
|
delete_object(instance, p1);
|
||||||
|
delete_tree(instance, p);
|
||||||
|
if (len > 0) {
|
||||||
|
p1 = new_string(instance, s1);
|
||||||
|
free(s1);
|
||||||
} else {
|
} else {
|
||||||
lisp_warn(instance, "expected an integer or float for integer conversion");
|
|
||||||
p1 = &alsa_lisp_nil;
|
p1 = &alsa_lisp_nil;
|
||||||
}
|
}
|
||||||
delete_tree(instance, p);
|
|
||||||
return p1;
|
return p1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Syntax: (compare-strings str1 start1 end1 str2 start2 end2 /opt-case-insensitive)
|
||||||
|
* 'str1' is first compared string
|
||||||
|
* 'start1' is first char (0..)
|
||||||
|
* 'end1' is last char (0..)
|
||||||
|
* 'str2' is second compared string
|
||||||
|
* 'start2' is first char (0..)
|
||||||
|
* 'end2' is last char (0..)
|
||||||
|
* /opt-case-insensitive true - case insensitive match
|
||||||
|
*/
|
||||||
|
struct alisp_object * F_compare_strings(struct alisp_instance *instance, struct alisp_object * args)
|
||||||
|
{
|
||||||
|
struct alisp_object * p1 = args, * n, * p[7];
|
||||||
|
char *s1, *s2;
|
||||||
|
int start1, end1, start2, end2;
|
||||||
|
|
||||||
|
for (start1 = 0; start1 < 7; start1++) {
|
||||||
|
p[start1] = eval(instance, car(p1));
|
||||||
|
p1 = cdr(n = p1);
|
||||||
|
delete_object(instance, n);
|
||||||
|
}
|
||||||
|
delete_tree(instance, p1);
|
||||||
|
if (alisp_compare_type(p[0], ALISP_OBJ_STRING)) {
|
||||||
|
lisp_warn(instance, "compare-strings: first argument must be string\n");
|
||||||
|
p1 = &alsa_lisp_nil;
|
||||||
|
goto __err;
|
||||||
|
}
|
||||||
|
if (alisp_compare_type(p[1], ALISP_OBJ_INTEGER)) {
|
||||||
|
lisp_warn(instance, "compare-strings: second argument must be integer\n");
|
||||||
|
p1 = &alsa_lisp_nil;
|
||||||
|
goto __err;
|
||||||
|
}
|
||||||
|
if (alisp_compare_type(p[2], ALISP_OBJ_INTEGER)) {
|
||||||
|
lisp_warn(instance, "compare-strings: third argument must be integer\n");
|
||||||
|
p1 = &alsa_lisp_nil;
|
||||||
|
goto __err;
|
||||||
|
}
|
||||||
|
if (alisp_compare_type(p[3], ALISP_OBJ_STRING)) {
|
||||||
|
lisp_warn(instance, "compare-strings: fifth argument must be string\n");
|
||||||
|
p1 = &alsa_lisp_nil;
|
||||||
|
goto __err;
|
||||||
|
}
|
||||||
|
if (!alisp_compare_type(p[4], ALISP_OBJ_NIL) &&
|
||||||
|
!alisp_compare_type(p[4], ALISP_OBJ_INTEGER)) {
|
||||||
|
lisp_warn(instance, "compare-strings: fourth argument must be integer\n");
|
||||||
|
p1 = &alsa_lisp_nil;
|
||||||
|
goto __err;
|
||||||
|
}
|
||||||
|
if (!alisp_compare_type(p[5], ALISP_OBJ_NIL) &&
|
||||||
|
!alisp_compare_type(p[5], ALISP_OBJ_INTEGER)) {
|
||||||
|
lisp_warn(instance, "compare-strings: sixth argument must be integer\n");
|
||||||
|
p1 = &alsa_lisp_nil;
|
||||||
|
goto __err;
|
||||||
|
}
|
||||||
|
s1 = p[0]->value.s;
|
||||||
|
start1 = p[1]->value.i;
|
||||||
|
end1 = p[2]->value.i;
|
||||||
|
s2 = p[3]->value.s;
|
||||||
|
start2 = alisp_compare_type(p[4], ALISP_OBJ_NIL) ? 0 : p[4]->value.i;
|
||||||
|
end2 = alisp_compare_type(p[5], ALISP_OBJ_NIL) ? start2 + (end1 - start1) : p[5]->value.i;
|
||||||
|
if (start1 < 0 || start2 < 0 || end1 < 0 || end2 < 0 ||
|
||||||
|
start1 >= (int)strlen(s1) || start2 >= (int)strlen(s2) ||
|
||||||
|
(end1 - start1) != (end2 - start2)) {
|
||||||
|
p1 = &alsa_lisp_nil;
|
||||||
|
goto __err;
|
||||||
|
}
|
||||||
|
if (p[6] != &alsa_lisp_nil) {
|
||||||
|
while (start1 < end1) {
|
||||||
|
if (s1[start1] == '\0' ||
|
||||||
|
s2[start2] == '\0' ||
|
||||||
|
tolower(s1[start1]) != tolower(s2[start2])) {
|
||||||
|
p1 = &alsa_lisp_nil;
|
||||||
|
goto __err;
|
||||||
|
}
|
||||||
|
start1++;
|
||||||
|
start2++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
while (start1 < end1) {
|
||||||
|
if (s1[start1] == '\0' ||
|
||||||
|
s2[start2] == '\0' ||
|
||||||
|
s1[start1] != s2[start2]) {
|
||||||
|
p1 = &alsa_lisp_nil;
|
||||||
|
goto __err;
|
||||||
|
}
|
||||||
|
start1++;
|
||||||
|
start2++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p1 = &alsa_lisp_t;
|
||||||
|
|
||||||
|
__err:
|
||||||
|
for (start1 = 0; start1 < 7; start1++)
|
||||||
|
delete_tree(instance, p[start1]);
|
||||||
|
return p1;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Syntax: (assoc key alist)
|
* Syntax: (assoc key alist)
|
||||||
*/
|
*/
|
||||||
|
|
@ -2744,9 +2990,10 @@ static struct intrinsic intrinsics[] = {
|
||||||
{ "assoc", F_assoc },
|
{ "assoc", F_assoc },
|
||||||
{ "assq", F_assq },
|
{ "assq", F_assq },
|
||||||
{ "atom", F_atom },
|
{ "atom", F_atom },
|
||||||
{ "call", F_call },
|
|
||||||
{ "car", F_car },
|
{ "car", F_car },
|
||||||
{ "cdr", F_cdr },
|
{ "cdr", F_cdr },
|
||||||
|
{ "compare-strings", F_compare_strings },
|
||||||
|
{ "concat", F_concat },
|
||||||
{ "cond", F_cond },
|
{ "cond", F_cond },
|
||||||
{ "cons", F_cons },
|
{ "cons", F_cons },
|
||||||
{ "defun", F_defun },
|
{ "defun", F_defun },
|
||||||
|
|
@ -2754,12 +3001,12 @@ static struct intrinsic intrinsics[] = {
|
||||||
{ "equal", F_equal },
|
{ "equal", F_equal },
|
||||||
{ "eval", F_eval },
|
{ "eval", F_eval },
|
||||||
{ "exfun", F_exfun },
|
{ "exfun", F_exfun },
|
||||||
{ "float", F_float },
|
{ "format", F_format },
|
||||||
|
{ "funcall", F_funcall },
|
||||||
{ "garbage-collect", F_gc },
|
{ "garbage-collect", F_gc },
|
||||||
{ "gc", F_gc },
|
{ "gc", F_gc },
|
||||||
{ "if", F_if },
|
{ "if", F_if },
|
||||||
{ "include", F_include },
|
{ "include", F_include },
|
||||||
{ "int", F_int },
|
|
||||||
{ "list", F_list },
|
{ "list", F_list },
|
||||||
{ "not", F_not },
|
{ "not", F_not },
|
||||||
{ "nth", F_nth },
|
{ "nth", F_nth },
|
||||||
|
|
@ -2776,9 +3023,11 @@ static struct intrinsic intrinsics[] = {
|
||||||
{ "set", F_set },
|
{ "set", F_set },
|
||||||
{ "setf", F_setq },
|
{ "setf", F_setq },
|
||||||
{ "setq", F_setq },
|
{ "setq", F_setq },
|
||||||
{ "str", F_str },
|
|
||||||
{ "string=", F_equal },
|
|
||||||
{ "string-equal", F_equal },
|
{ "string-equal", F_equal },
|
||||||
|
{ "string-to-float", F_string_to_float },
|
||||||
|
{ "string-to-integer", F_string_to_integer },
|
||||||
|
{ "string-to-number", F_string_to_float },
|
||||||
|
{ "string=", F_equal },
|
||||||
{ "unless", F_unless },
|
{ "unless", F_unless },
|
||||||
{ "unset", F_unset },
|
{ "unset", F_unset },
|
||||||
{ "unsetf", F_unsetq },
|
{ "unsetf", F_unsetq },
|
||||||
|
|
@ -2795,7 +3044,7 @@ static int compar(const void *p1, const void *p2)
|
||||||
((struct intrinsic *)p2)->name);
|
((struct intrinsic *)p2)->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct alisp_object * eval_cons1(struct alisp_instance *instance, struct alisp_object * p1, struct alisp_object * p2)
|
static inline struct alisp_object * eval_cons1(struct alisp_instance *instance, struct alisp_object * p1, struct alisp_object * p2)
|
||||||
{
|
{
|
||||||
struct alisp_object * p3;
|
struct alisp_object * p3;
|
||||||
struct intrinsic key, *item;
|
struct intrinsic key, *item;
|
||||||
|
|
@ -2828,6 +3077,26 @@ static struct alisp_object * eval_cons1(struct alisp_instance *instance, struct
|
||||||
return &alsa_lisp_nil;
|
return &alsa_lisp_nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Syntax: (funcall function args...)
|
||||||
|
*/
|
||||||
|
static struct alisp_object * F_funcall(struct alisp_instance *instance, struct alisp_object * args)
|
||||||
|
{
|
||||||
|
struct alisp_object * p = eval(instance, car(args)), * p1;
|
||||||
|
|
||||||
|
if (!alisp_compare_type(p, ALISP_OBJ_IDENTIFIER) &&
|
||||||
|
!alisp_compare_type(p, ALISP_OBJ_STRING)) {
|
||||||
|
lisp_warn(instance, "expected an function name");
|
||||||
|
delete_tree(instance, p);
|
||||||
|
delete_tree(instance, cdr(args));
|
||||||
|
delete_object(instance, args);
|
||||||
|
return &alsa_lisp_nil;
|
||||||
|
}
|
||||||
|
p1 = cdr(args);
|
||||||
|
delete_object(instance, args);
|
||||||
|
return eval_cons1(instance, p, p1);
|
||||||
|
}
|
||||||
|
|
||||||
static inline struct alisp_object * eval_cons(struct alisp_instance *instance, struct alisp_object * p)
|
static inline struct alisp_object * eval_cons(struct alisp_instance *instance, struct alisp_object * p)
|
||||||
{
|
{
|
||||||
struct alisp_object * p1 = car(p), * p2;
|
struct alisp_object * p1 = car(p), * p2;
|
||||||
|
|
@ -2839,6 +3108,8 @@ static inline struct alisp_object * eval_cons(struct alisp_instance *instance, s
|
||||||
p2 = cdr(p);
|
p2 = cdr(p);
|
||||||
delete_object(instance, p);
|
delete_object(instance, p);
|
||||||
return eval_cons1(instance, p1, p2);
|
return eval_cons1(instance, p1, p2);
|
||||||
|
} else {
|
||||||
|
delete_tree(instance, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
return &alsa_lisp_nil;
|
return &alsa_lisp_nil;
|
||||||
|
|
@ -2919,6 +3190,7 @@ static int alisp_include_file(struct alisp_instance *instance, const char *filen
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
snd_input_close(instance->in);
|
||||||
_err:
|
_err:
|
||||||
free(name);
|
free(name);
|
||||||
instance->in = old_in;
|
instance->in = old_in;
|
||||||
|
|
@ -3141,12 +3413,21 @@ int alsa_lisp_function(struct alisp_instance *instance, struct alisp_seq_iterato
|
||||||
}
|
}
|
||||||
if (res == NULL)
|
if (res == NULL)
|
||||||
err = -ENOMEM;
|
err = -ENOMEM;
|
||||||
if (err == 0 && result)
|
if (err == 0 && result) {
|
||||||
*result = res;
|
*result = res;
|
||||||
|
} else {
|
||||||
|
delete_tree(instance, res);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void alsa_lisp_result_free(struct alisp_instance *instance,
|
||||||
|
struct alisp_seq_iterator *result)
|
||||||
|
{
|
||||||
|
delete_tree(instance, result);
|
||||||
|
}
|
||||||
|
|
||||||
int alsa_lisp_seq_first(struct alisp_instance *instance, const char *id,
|
int alsa_lisp_seq_first(struct alisp_instance *instance, const char *id,
|
||||||
struct alisp_seq_iterator **seq)
|
struct alisp_seq_iterator **seq)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,11 @@
|
||||||
(defun sndoc_mixer_open (hctl)
|
;
|
||||||
(princ "sndoc_mixer_open\n")
|
; SiS SI7018 mixer abstract layer
|
||||||
|
;
|
||||||
|
; Copyright (c) 2003 Jaroslav Kysela <perex@suse.cz>
|
||||||
|
; License: GPL v2 (http://www.gnu.org/licenses/gpl.html)
|
||||||
|
;
|
||||||
|
|
||||||
|
(defun sndoc_mixer_open (hctl pcm)
|
||||||
|
(princ "sndoc_mixer_open: hctl=" hctl " pcm=" pcm "\n")
|
||||||
0
|
0
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,11 @@
|
||||||
(defun sndop_mixer_open (hctl)
|
;
|
||||||
(princ "sndop_mixer_open\n")
|
; SiS SI7018 mixer abstract layer
|
||||||
|
;
|
||||||
|
; Copyright (c) 2003 Jaroslav Kysela <perex@suse.cz>
|
||||||
|
; License: GPL v2 (http://www.gnu.org/licenses/gpl.html)
|
||||||
|
;
|
||||||
|
|
||||||
|
(defun sndop_mixer_open (hctl pcm)
|
||||||
|
(princ "sndop_mixer_open: hctl=" hctl " pcm=" pcm "\n")
|
||||||
0
|
0
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,20 @@
|
||||||
(setq snd_card_aliases_array
|
(setq snd_card_aliases_array
|
||||||
(
|
(
|
||||||
("YMF724" . "YMF744")
|
("YMF724" . "YMF744")
|
||||||
("YMF724F" . "YMF744")
|
("YMF724F" . "YMF744")
|
||||||
("YMF740" . "YMF744")
|
("YMF740" . "YMF744")
|
||||||
("YMF740C" . "YMF744")
|
("YMF740C" . "YMF744")
|
||||||
("YMF754" . "YMF744")
|
("YMF754" . "YMF744")
|
||||||
("CMIPCI" . "CMI8338")
|
("CMIPCI" . "CMI8338")
|
||||||
("CMI8738" . "CMI8338")
|
("CMI8738" . "CMI8338")
|
||||||
("CMI8738-MC4" . "CMI8738-MC6")
|
("CMI8738-MC4" . "CMI8738-MC6")
|
||||||
("E-mu APS" . "EMU10K1")
|
("E-mu APS" . "EMU10K1")
|
||||||
("GUS Max" . "GUS")
|
("GUS Max" . "GUS")
|
||||||
("GUS ACE" . "GUS")
|
("GUS ACE" . "GUS")
|
||||||
("GUS Extreme" . "GUS")
|
("GUS Extreme" . "GUS")
|
||||||
("AMD InterWave" . "GUS")
|
("AMD InterWave" . "GUS")
|
||||||
("Dynasonic 3-D" . "GUS")
|
("Dynasonic 3-D" . "GUS")
|
||||||
("InterWave STB" . "GUS")
|
("InterWave STB" . "GUS")
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,9 @@
|
||||||
;
|
;
|
||||||
; Toplevel configuration for the ALSA Ordinary Mixer Interface
|
; Toplevel configuration for the ALSA Ordinary Mixer Interface
|
||||||
;
|
;
|
||||||
|
; Copyright (c) 2003 Jaroslav Kysela <perex@suse.cz>
|
||||||
|
; License: GPL v2 (http://www.gnu.org/licenses/gpl.html)
|
||||||
|
;
|
||||||
|
|
||||||
(defun sndo_include (hctl stream)
|
(defun sndo_include (hctl stream)
|
||||||
(setq info (Acall "ctl_card_info" (Acall "hctl_ctl" hctl)))
|
(setq info (Acall "ctl_card_info" (Acall "hctl_ctl" hctl)))
|
||||||
|
|
@ -8,7 +11,7 @@
|
||||||
(progn
|
(progn
|
||||||
(setq info (Aresult info))
|
(setq info (Aresult info))
|
||||||
(setq driver (cdr (assq "driver" (unsetq info))))
|
(setq driver (cdr (assq "driver" (unsetq info))))
|
||||||
(setq file (+ (path "data") "/alsa/cards/" (snd_card_alias driver) "/sndo" stream "-mixer.alisp"))
|
(setq file (concat (path "data") "/alsa/cards/" (snd_card_alias driver) "/sndo" stream "-mixer.alisp"))
|
||||||
(setq r (include file))
|
(setq r (include file))
|
||||||
(when (= r -2) (Asyserr "unable to find file " file))
|
(when (= r -2) (Asyserr "unable to find file " file))
|
||||||
)
|
)
|
||||||
|
|
@ -17,36 +20,55 @@
|
||||||
(unsetq info driver file r)
|
(unsetq info driver file r)
|
||||||
)
|
)
|
||||||
|
|
||||||
(defun sndo_mixer_open_fcn (stream)
|
(defun sndo_mixer_open_fcn (hctl stream pcm)
|
||||||
(setq fcn (+ "sndo" stream "_mixer_open"))
|
(setq fcn (concat "sndo" stream "_mixer_open"))
|
||||||
(setq r (if (exfun fcn) (call fcn hctl) 0))
|
(setq r (if (exfun fcn) (funcall fcn hctl pcm) 0))
|
||||||
(when (= r 0)
|
(when (= r 0)
|
||||||
(setq hctls (if hctls (cons hctls (cons hctl)) hctl))
|
(setq hctls (if hctls (cons hctls (cons hctl)) hctl))
|
||||||
)
|
)
|
||||||
(unsetq fcn r)
|
(unsetq fcn r)
|
||||||
)
|
)
|
||||||
|
|
||||||
(defun sndo_mixer_open_hctl (card stream)
|
(defun sndo_mixer_open_hctl (name stream pcm)
|
||||||
(setq hctl (Acall "hctl_open" (+ "hw:" (str card)) nil))
|
(setq hctl (Acall "hctl_open" name nil))
|
||||||
(setq r (Aerror hctl))
|
(setq r (Aerror hctl))
|
||||||
(when (= r 0)
|
(when (= r 0)
|
||||||
(setq hctl (Aresult hctl))
|
(setq hctl (Aresult hctl))
|
||||||
(setq r (sndo_include hctl stream))
|
(setq r (sndo_include hctl stream))
|
||||||
(when (= r 0) (setq r (sndo_mixer_open_fcn stream)))
|
(if (= r 0)
|
||||||
|
(setq r (sndo_mixer_open_fcn hctl stream pcm))
|
||||||
|
(Acall "hctl_close" hctl)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
(unsetq hctl r)
|
(unsetq hctl r)
|
||||||
)
|
)
|
||||||
|
|
||||||
(defun sndo_mixer_open_virtual (pcm stream)
|
(defun sndo_mixer_open_virtual (name stream pcm)
|
||||||
(setq name (Acall "pcm_name" pcm))
|
(setq file (concat (path "data") "/alsa/virtual/" name "/sndo" stream "-mixer.alisp"))
|
||||||
(setq file (+ (path "data") "/alsa/virtual/" name "/sndo" stream "-mixer.alisp"))
|
|
||||||
(setq r (include file))
|
(setq r (include file))
|
||||||
(when (= r -2) (Asyserr "unable to find file " file))
|
(when (= r -2) (Asyserr "unable to find file " file))
|
||||||
(when (= r 0) (setq r (sndo_mixer_open_fcn stream)))
|
(when (= r 0) (setq r (sndo_mixer_open_fcn nil stream pcm)))
|
||||||
(unsetq name file r)
|
(unsetq file r)
|
||||||
)
|
)
|
||||||
|
|
||||||
(defun sndo_mixer_open1 (pcm stream)
|
(defun sndo_mixer_open1 (name stream)
|
||||||
|
(if (compare-strings name 0 2 "hw:" 0 2)
|
||||||
|
(sndo_mixer_open_hctl name stream nil)
|
||||||
|
(sndo_mixer_open_virtual name stream nil)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
(defun sndo_mixer_open (pname cname)
|
||||||
|
(setq r (sndo_mixer_open1 pname "p"))
|
||||||
|
(when (= r 0) (setq r (sndo_mixer_open1 cname "c")))
|
||||||
|
(when (!= r 0) (sndo_mixer_close))
|
||||||
|
(unsetq sndo_mixer_open
|
||||||
|
sndo_mixer_open_pcm sndo_mixer_open_pcm1
|
||||||
|
sndo_mixer_open_virtual sndo_mixer_open_fcn
|
||||||
|
sndo_include r)
|
||||||
|
)
|
||||||
|
|
||||||
|
(defun sndo_mixer_open_pcm1 (pcm stream)
|
||||||
(setq info (Acall "pcm_info" pcm))
|
(setq info (Acall "pcm_info" pcm))
|
||||||
(setq r (Aerror info))
|
(setq r (Aerror info))
|
||||||
(when (= r 0)
|
(when (= r 0)
|
||||||
|
|
@ -54,19 +76,20 @@
|
||||||
(setq card (cdr (assq "card" info)))
|
(setq card (cdr (assq "card" info)))
|
||||||
(setq r
|
(setq r
|
||||||
(if (< card 0)
|
(if (< card 0)
|
||||||
(sndo_mixer_open_virtual pcm stream)
|
(sndo_mixer_open_virtual (Acall "pcm_name" pcm) stream pcm)
|
||||||
(sndo_mixer_open_hctl card stream)
|
(sndo_mixer_open_hctl (format "hw:%i" card) stream pcm)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(unsetq info card r)
|
(unsetq info card r)
|
||||||
)
|
)
|
||||||
|
|
||||||
(defun sndo_mixer_open (ppcm cpcm)
|
(defun sndo_mixer_open_pcm (ppcm cpcm)
|
||||||
(setq r (sndo_mixer_open1 ppcm "p"))
|
(setq r (sndo_mixer_open_pcm1 ppcm "p"))
|
||||||
(when (= r 0) (setq r (sndo_mixer_open1 cpcm "c")))
|
(when (= r 0) (setq r (sndo_mixer_open_pcm1 cpcm "c")))
|
||||||
(when (!= r 0) (sndo_mixer_close))
|
(when (!= r 0) (sndo_mixer_close))
|
||||||
(unsetq sndo_mixer_open sndo_mixer_open1
|
(unsetq sndo_mixer_open
|
||||||
|
sndo_mixer_open_pcm sndo_mixer_open_pcm1
|
||||||
sndo_mixer_open_virtual sndo_mixer_open_fcn
|
sndo_mixer_open_virtual sndo_mixer_open_fcn
|
||||||
sndo_include r)
|
sndo_include r)
|
||||||
)
|
)
|
||||||
|
|
@ -74,8 +97,8 @@
|
||||||
(defun sndo_mixer_close1 (hctl stream)
|
(defun sndo_mixer_close1 (hctl stream)
|
||||||
(when hctl
|
(when hctl
|
||||||
(progn
|
(progn
|
||||||
(setq fcn (+ "sndo" stream "_mixer_close"))
|
(setq fcn (concat "sndo" stream "_mixer_close"))
|
||||||
(when (exfun fcn) (call fcn hctl))
|
(when (exfun fcn) (funcall fcn hctl))
|
||||||
(unsetq fcn)
|
(unsetq fcn)
|
||||||
(Acall "hctl_close" hctl)
|
(Acall "hctl_close" hctl)
|
||||||
)
|
)
|
||||||
|
|
@ -88,4 +111,4 @@
|
||||||
(unsetq hctls)
|
(unsetq hctls)
|
||||||
)
|
)
|
||||||
|
|
||||||
(include (+ (path "data") "/alsa/cards/aliases.alisp"))
|
(include (concat (path "data") "/alsa/cards/aliases.alisp"))
|
||||||
|
|
|
||||||
|
|
@ -67,18 +67,12 @@ struct sndo_mixer {
|
||||||
int _free_cfg;
|
int _free_cfg;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
int sndo_mixer_open1(sndo_mixer_t **pmixer,
|
||||||
* \brief Opens a ordinary mixer instance
|
const char *lisp_fcn,
|
||||||
* \param pmixer Returned ordinary mixer handle
|
const char *lisp_fmt,
|
||||||
* \param playback_pcm handle of the playback PCM
|
const void *parg,
|
||||||
* \param capture_pcm handle of the capture PCM
|
const void *carg,
|
||||||
* \param lconf Local configuration (might be NULL - use global configuration)
|
struct alisp_cfg *lconf)
|
||||||
* \return 0 on success otherwise a negative error code
|
|
||||||
*/
|
|
||||||
int sndo_mixer_open(sndo_mixer_t **pmixer,
|
|
||||||
snd_pcm_t *playback_pcm,
|
|
||||||
snd_pcm_t *capture_pcm,
|
|
||||||
struct alisp_cfg *lconf)
|
|
||||||
{
|
{
|
||||||
struct alisp_cfg *cfg = lconf;
|
struct alisp_cfg *cfg = lconf;
|
||||||
struct alisp_instance *alisp;
|
struct alisp_instance *alisp;
|
||||||
|
|
@ -101,16 +95,16 @@ int sndo_mixer_open(sndo_mixer_t **pmixer,
|
||||||
cfg = alsa_lisp_default_cfg(input);
|
cfg = alsa_lisp_default_cfg(input);
|
||||||
if (cfg == NULL)
|
if (cfg == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
cfg->warning = 1;
|
||||||
#if 0
|
#if 0
|
||||||
cfg->debug = 1;
|
cfg->debug = 1;
|
||||||
cfg->verbose = 1;
|
cfg->verbose = 1;
|
||||||
cfg->warning = 1;
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
err = alsa_lisp(cfg, &alisp);
|
err = alsa_lisp(cfg, &alisp);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto __error;
|
goto __error;
|
||||||
err = alsa_lisp_function(alisp, &iterator, "sndo_mixer_open", "%ppcm%ppcm", playback_pcm, capture_pcm);
|
err = alsa_lisp_function(alisp, &iterator, lisp_fcn, lisp_fmt, parg, carg);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
alsa_lisp_free(alisp);
|
alsa_lisp_free(alisp);
|
||||||
goto __error;
|
goto __error;
|
||||||
|
|
@ -118,6 +112,7 @@ int sndo_mixer_open(sndo_mixer_t **pmixer,
|
||||||
err = alsa_lisp_seq_integer(iterator, &val);
|
err = alsa_lisp_seq_integer(iterator, &val);
|
||||||
if (err == 0 && val < 0)
|
if (err == 0 && val < 0)
|
||||||
err = val;
|
err = val;
|
||||||
|
alsa_lisp_result_free(alisp, iterator);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
alsa_lisp_free(alisp);
|
alsa_lisp_free(alisp);
|
||||||
goto __error;
|
goto __error;
|
||||||
|
|
@ -157,6 +152,39 @@ int sndo_mixer_open(sndo_mixer_t **pmixer,
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Opens a ordinary mixer instance
|
||||||
|
* \param pmixer Returned ordinary mixer handle
|
||||||
|
* \param playback_name name for playback HCTL communication
|
||||||
|
* \param capture_name name for capture HCTL communication
|
||||||
|
* \param lconf Local configuration (might be NULL - use global configuration)
|
||||||
|
* \return 0 on success otherwise a negative error code
|
||||||
|
*/
|
||||||
|
int sndo_mixer_open(sndo_mixer_t **pmixer,
|
||||||
|
const char *playback_name,
|
||||||
|
const char *capture_name,
|
||||||
|
struct alisp_cfg *lconf)
|
||||||
|
{
|
||||||
|
return sndo_mixer_open1(pmixer, "sndo_mixer_open", "%s%s", playback_name, capture_name, lconf);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Opens a ordinary mixer instance
|
||||||
|
* \param pmixer Returned ordinary mixer handle
|
||||||
|
* \param playback_pcm handle of the playback PCM
|
||||||
|
* \param capture_pcm handle of the capture PCM
|
||||||
|
* \param lconf Local configuration (might be NULL - use global configuration)
|
||||||
|
* \return 0 on success otherwise a negative error code
|
||||||
|
*/
|
||||||
|
int sndo_mixer_open_pcm(sndo_mixer_t **pmixer,
|
||||||
|
snd_pcm_t *playback_pcm,
|
||||||
|
snd_pcm_t *capture_pcm,
|
||||||
|
struct alisp_cfg *lconf)
|
||||||
|
{
|
||||||
|
return sndo_mixer_open1(pmixer, "sndo_mixer_open_pcm", "%ppcm%ppcm", playback_pcm, capture_pcm, lconf);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Closes a ordinary mixer instance
|
* \brief Closes a ordinary mixer instance
|
||||||
* \param mixer Ordinary mixer handle to close
|
* \param mixer Ordinary mixer handle to close
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ int main(int argc, char *argv[])
|
||||||
{"cname", 1, NULL, 'C'},
|
{"cname", 1, NULL, 'C'},
|
||||||
{NULL, 0, NULL, 0},
|
{NULL, 0, NULL, 0},
|
||||||
};
|
};
|
||||||
int err, morehelp;
|
int err, morehelp, result = EXIT_SUCCESS;
|
||||||
char *pname = "default", *cname = "default";
|
char *pname = "default", *cname = "default";
|
||||||
snd_pcm_t *phandle = NULL, *chandle = NULL;
|
snd_pcm_t *phandle = NULL, *chandle = NULL;
|
||||||
sndo_mixer_t *handle;
|
sndo_mixer_t *handle;
|
||||||
|
|
@ -59,7 +59,8 @@ int main(int argc, char *argv[])
|
||||||
err = snd_pcm_open(&phandle, pname, SND_PCM_STREAM_PLAYBACK, 0);
|
err = snd_pcm_open(&phandle, pname, SND_PCM_STREAM_PLAYBACK, 0);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
fprintf(stderr, "Playback PCM open error: %s\n", snd_strerror(err));
|
fprintf(stderr, "Playback PCM open error: %s\n", snd_strerror(err));
|
||||||
return EXIT_FAILURE;
|
result = EXIT_FAILURE;
|
||||||
|
goto __end;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -69,17 +70,23 @@ int main(int argc, char *argv[])
|
||||||
if (phandle)
|
if (phandle)
|
||||||
snd_pcm_close(phandle);
|
snd_pcm_close(phandle);
|
||||||
fprintf(stderr, "Capture PCM open error: %s\n", snd_strerror(err));
|
fprintf(stderr, "Capture PCM open error: %s\n", snd_strerror(err));
|
||||||
return EXIT_FAILURE;
|
result = EXIT_FAILURE;
|
||||||
|
goto __end;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = sndo_mixer_open(&handle, phandle, chandle, NULL);
|
err = sndo_mixer_open_pcm(&handle, phandle, chandle, NULL);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
fprintf(stderr, "mixer open error: %s\n", snd_strerror(err));
|
fprintf(stderr, "mixer open error: %s\n", snd_strerror(err));
|
||||||
return EXIT_FAILURE;
|
result = EXIT_FAILURE;
|
||||||
|
} else {
|
||||||
|
sndo_mixer_close(handle);
|
||||||
}
|
}
|
||||||
sndo_mixer_close(handle);
|
__end:
|
||||||
snd_pcm_close(chandle);
|
if (chandle)
|
||||||
snd_pcm_close(phandle);
|
snd_pcm_close(chandle);
|
||||||
return EXIT_SUCCESS;
|
if (phandle)
|
||||||
|
snd_pcm_close(phandle);
|
||||||
|
snd_config_update_free_global(); /* to keep valgrind happy */
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue