m_atom.c 4.32 KB
Newer Older
Miller Puckette's avatar
Miller Puckette committed
1
2
3
4
5
6
7
8
/* Copyright (c) 1997-1999 Miller Puckette.
* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution.  */

#include "m_pd.h"
#include <stdio.h>
#include <string.h>

9
10
#define DOLLARALL -0x7fffffff /* defined in m_binbuf.c, too. Consider merging */

Miller Puckette's avatar
Miller Puckette committed
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
    /* convenience routines for checking and getting values of
        atoms.  There's no "pointer" version since there's nothing
        safe to return if there's an error. */

t_float atom_getfloat(t_atom *a)
{
    if (a->a_type == A_FLOAT) return (a->a_w.w_float);
    else return (0);
}

t_int atom_getint(t_atom *a)
{
    return (atom_getfloat(a));
}

t_symbol *atom_getsymbol(t_atom *a)  /* LATER think about this more carefully */
{
    if (a->a_type == A_SYMBOL) return (a->a_w.w_symbol);
    else return (&s_float);
}

Hans-Christoph Steiner's avatar
Hans-Christoph Steiner committed
32
33
34
35
36
37
38
39
t_blob *atom_getblob(t_atom *a)  /* MP 20070108 */
{
    static unsigned char c = 0;/* a default blob to avoid null pointers. This should be somewhere else...? */
    static t_blob st = {1L, &c};
    if (a->a_type == A_BLOB) return (a->a_w.w_blob);
    else return (&st);
}

Miller Puckette's avatar
Miller Puckette committed
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
t_symbol *atom_gensym(t_atom *a)  /* this works  better for graph labels */
{
    char buf[30];
    if (a->a_type == A_SYMBOL) return (a->a_w.w_symbol);
    else if (a->a_type == A_FLOAT)
        sprintf(buf, "%g", a->a_w.w_float);
    else strcpy(buf, "???");
    return (gensym(buf));
}

t_float atom_getfloatarg(int which, int argc, t_atom *argv)
{
    if (argc <= which) return (0);
    argv += which;
    if (argv->a_type == A_FLOAT) return (argv->a_w.w_float);
    else return (0);
}

t_int atom_getintarg(int which, int argc, t_atom *argv)
{
    return (atom_getfloatarg(which, argc, argv));
}

t_symbol *atom_getsymbolarg(int which, int argc, t_atom *argv)
{
    if (argc <= which) return (&s_);
    argv += which;
    if (argv->a_type == A_SYMBOL) return (argv->a_w.w_symbol);
    else return (&s_);
}

/* convert an atom into a string, in the reverse sense of binbuf_text (q.v.)
* special attention is paid to symbols containing the special characters
* ';', ',', '$', and '\'; these are quoted with a preceding '\', except that
* the '$' only gets quoted at the beginning of the string.
*/

void atom_string(t_atom *a, char *buf, unsigned int bufsize)
{
    char tbuf[30];
    switch(a->a_type)
    {
    case A_SEMI: strcpy(buf, ";"); break;
    case A_COMMA: strcpy(buf, ","); break;
    case A_POINTER:
        strcpy(buf, "(pointer)");
        break;
    case A_FLOAT:
        sprintf(tbuf, "%g", a->a_w.w_float);
        if (strlen(tbuf) < bufsize-1) strcpy(buf, tbuf);
        else if (a->a_w.w_float < 0) strcpy(buf, "-");
        else  strcat(buf, "+");
        break;
    case A_SYMBOL:
    {
        char *sp;
        unsigned int len;
        int quote;
98
        if(!strcmp(a->a_w.w_symbol->s_name, "$@")) /* JMZ: #@ quoting */
99
            quote=1;
100
        else
101
102
103
104
105
106
        {
            for (sp = a->a_w.w_symbol->s_name, len = 0, quote = 0; *sp; sp++, len++)
                if (*sp == ';' || *sp == ',' || *sp == '\\' || 
                    (*sp == '$' && sp[1] >= '0' && sp[1] <= '9'))
                    quote = 1;
        }
Miller Puckette's avatar
Miller Puckette committed
107
108
109
110
111
112
113
        if (quote)
        {
            char *bp = buf, *ep = buf + (bufsize-2);
            sp = a->a_w.w_symbol->s_name;
            while (bp < ep && *sp)
            {
                if (*sp == ';' || *sp == ',' || *sp == '\\' ||
114
                    (*sp == '$' && ((sp[1] >= '0' && sp[1] <= '9')||sp[1]=='@')))
Miller Puckette's avatar
Miller Puckette committed
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
                        *bp++ = '\\';
                *bp++ = *sp++;
            }
            if (*sp) *bp++ = '*';
            *bp = 0;
            /* post("quote %s -> %s", a->a_w.w_symbol->s_name, buf); */
        }
        else
        {
            if (len < bufsize-1) strcpy(buf, a->a_w.w_symbol->s_name);
            else
            {
                strncpy(buf, a->a_w.w_symbol->s_name, bufsize - 2);
                strcpy(buf + (bufsize - 2), "*");
            }
        }
    }
        break;
    case A_DOLLAR:
134
        if(a->a_w.w_index == DOLLARALL)
135
136
137
138
139
140
141
142
        {
            /* JMZ: $@ expansion */
            sprintf(buf, "$@");
        }
        else
        {
            sprintf(buf, "$%d", a->a_w.w_index);
        }
Miller Puckette's avatar
Miller Puckette committed
143
144
145
146
147
148
149
150
151
        break;
    case A_DOLLSYM:
        strncpy(buf, a->a_w.w_symbol->s_name, bufsize);
        buf[bufsize-1] = 0;
        break;
    default:
        bug("atom_string");
    }
}