Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Jonathan Wilkes
purr-data
Commits
11f6610d
Commit
11f6610d
authored
Jul 06, 2020
by
Jonathan Wilkes
Browse files
Merge branch 'port-float-symbol-method'
parents
5a20d90f
4fc8e6cd
Pipeline
#2186
passed with stage
in 296 minutes and 1 second
Changes
7
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
pd/src/m_atom.c
View file @
11f6610d
...
...
@@ -44,7 +44,7 @@ t_blob *atom_getblob(t_atom *a) /* MP 20070108 */
else
return
(
&
st
);
}
t_symbol
*
atom_gensym
(
t_atom
*
a
)
/* this works
better for graph labels */
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
);
...
...
pd/src/m_class.c
View file @
11f6610d
...
...
@@ -43,9 +43,108 @@ t_classtable *ct;
static
t_symbol
*
class_extern_dir
=
&
s_
;
int
symbol_can_float
(
t_symbol
*
s
,
t_float
*
f
);
/* try to give the user some help with the uglier cases of unexpected
atom types in messages.
dostof flag controls whether we want to try to convert a symbol
to a float.
for [float]'s symbol conversion we even check if we received an
out of range error, but here for the general case we don't do that. */
char
*
type_hint
(
t_symbol
*
s
,
int
argc
,
t_atom
*
argv
,
int
dostof
)
{
static
char
hint
[
MAXPDSTRING
];
t_float
f
=
0
;
/* Null selectors-- the user typically shouldn't encounter these,
especially one that triggers an unknown method error. But we
check for them anyway. */
if
(
!
s
)
{
sprintf
(
hint
,
" (Note: null selector detected)"
);
return
hint
;
}
/* Empty symbol selector is also rare. But a user can easily generate
one with [symbol( or [symbol] then send to [list trim]. */
if
(
s
==
&
s_
)
{
sprintf
(
hint
,
" (Note: empty symbol selector detected)"
);
return
hint
;
}
/* More commonly, the user may have a "symbol" message where the
payload is an empty symbol. This can cause confusion for debugging
since the empty symbol doesn't print out anything. */
if
(
s
&&
s
==
&
s_symbol
&&
argc
&&
argv
->
a_type
==
A_SYMBOL
&&
argv
->
a_w
.
w_symbol
==
&
s_
)
{
sprintf
(
hint
,
" (Note: symbol message with empty payload detected)"
);
return
hint
;
}
/* Somewhat common edge case-- [makefilename] and other objects can
output a symbol message with a payload that looks numeric but is
indeed a symbol atom. In fact, Pd's text parser would interpret
such a string as a float if you sent it through the parser.
This can cause problems if the user tries to serialize the data
and read it back-- say, by saving the symbol message "symbol 123"
in a file. The next time they load it, "123" will be parsed as
a float atom, and any symbol methods will read from the wrong
union field and (probably) interpret it as an empty symbol. */
if
(
dostof
)
{
if
(
symbol_can_float
(
atom_getsymbolarg
(
0
,
argc
,
argv
),
&
f
))
{
sprintf
(
hint
,
" (Note: this symbol message has a floatlike payload "
"which cannot be saved properly. Did you mean 'float %s'?)"
,
argv
->
a_w
.
w_symbol
->
s_name
);
return
hint
;
}
else
if
(
f
==
-
1
||
f
==
1
)
{
/* For values which would overflow, give a hint but don't
suggest float type */
sprintf
(
hint
,
" (Note: this symbol message has an %s floatlike "
"payload which cannot be saved properly."
,
f
==
1
?
"overflowing"
:
"underflowing"
);
return
hint
;
}
}
/* Rather uncommon case where the selector itself is a symbol atom
that would normally have been parsed as a float. */
if
(
dostof
)
{
if
(
symbol_can_float
(
s
,
&
f
))
{
sprintf
(
hint
,
" (Note: %s looks like a float but is actually a "
"symbol atom which cannot be saved properly)"
,
s
->
s_name
);
return
hint
;
}
else
if
(
f
==
-
1
||
f
==
1
)
{
/* For values which would overflow, give a hint but don't
suggest float type */
sprintf
(
hint
,
" (Note: this symbol atom has an %s floatlike "
"payload which cannot be saved properly."
,
f
==
1
?
"overflowing"
:
"underflowing"
);
return
hint
;
}
}
hint
[
0
]
=
'\0'
;
return
hint
;
}
static
void
pd_defaultanything
(
t_pd
*
x
,
t_symbol
*
s
,
int
argc
,
t_atom
*
argv
)
{
pd_error
(
x
,
"%s: no method for '%s'"
,
(
*
x
)
->
c_name
->
s_name
,
s
->
s_name
);
pd_error
(
x
,
"%s: no method for '%s'%s"
,
(
*
x
)
->
c_name
->
s_name
,
s
->
s_name
,
type_hint
(
s
,
argc
,
argv
,
*
(
*
x
)
->
c_floatmethod
!=
pd_defaultfloat
?
1
:
0
));
}
static
void
pd_defaultbang
(
t_pd
*
x
)
...
...
pd/src/m_obj.c
View file @
11f6610d
...
...
@@ -72,10 +72,12 @@ t_inlet *signalinlet_new(t_object *owner, t_float f)
return
(
x
);
}
static
void
inlet_wrong
(
t_inlet
*
x
,
t_symbol
*
s
)
char
*
type_hint
(
t_symbol
*
s
,
int
argc
,
t_atom
*
argv
,
int
dostof
);
static
void
inlet_wrong
(
t_inlet
*
x
,
t_symbol
*
s
,
int
argc
,
t_atom
*
argv
)
{
pd_error
(
x
->
i_owner
,
"inlet: expected '%s' but got '%s'"
,
x
->
i_symfrom
->
s_name
,
s
->
s_name
);
pd_error
(
x
->
i_owner
,
"inlet: expected '%s' but got '%s'
%s
"
,
x
->
i_symfrom
->
s_name
,
s
->
s_name
,
type_hint
(
s
,
argc
,
argv
,
1
)
);
}
static
void
inlet_list
(
t_inlet
*
x
,
t_symbol
*
s
,
int
argc
,
t_atom
*
argv
);
...
...
@@ -88,7 +90,7 @@ static void inlet_bang(t_inlet *x)
else
if
(
!
x
->
i_symfrom
)
pd_bang
(
x
->
i_dest
);
else
if
(
x
->
i_symfrom
==
&
s_list
)
inlet_list
(
x
,
&
s_bang
,
0
,
0
);
else
inlet_wrong
(
x
,
&
s_bang
);
else
inlet_wrong
(
x
,
&
s_bang
,
0
,
0
);
}
static
void
inlet_pointer
(
t_inlet
*
x
,
t_gpointer
*
gp
)
...
...
@@ -102,7 +104,7 @@ static void inlet_pointer(t_inlet *x, t_gpointer *gp)
SETPOINTER
(
&
a
,
gp
);
inlet_list
(
x
,
&
s_pointer
,
1
,
&
a
);
}
else
inlet_wrong
(
x
,
&
s_pointer
);
else
inlet_wrong
(
x
,
&
s_pointer
,
0
,
0
);
}
static
void
inlet_float
(
t_inlet
*
x
,
t_float
f
)
...
...
@@ -119,7 +121,7 @@ static void inlet_float(t_inlet *x, t_float f)
SETFLOAT
(
&
a
,
f
);
inlet_list
(
x
,
&
s_float
,
1
,
&
a
);
}
else
inlet_wrong
(
x
,
&
s_float
);
else
inlet_wrong
(
x
,
&
s_float
,
0
,
0
);
}
static
void
inlet_symbol
(
t_inlet
*
x
,
t_symbol
*
s
)
...
...
@@ -127,13 +129,15 @@ static void inlet_symbol(t_inlet *x, t_symbol *s)
if
(
x
->
i_symfrom
==
&
s_symbol
)
pd_vmess
(
x
->
i_dest
,
x
->
i_symto
,
"s"
,
s
);
else
if
(
!
x
->
i_symfrom
)
pd_symbol
(
x
->
i_dest
,
s
);
else
if
(
x
->
i_symfrom
==
&
s_list
)
else
{
t_atom
a
;
SETSYMBOL
(
&
a
,
s
);
inlet_list
(
x
,
&
s_symbol
,
1
,
&
a
);
if
(
x
->
i_symfrom
==
&
s_list
)
inlet_list
(
x
,
&
s_symbol
,
1
,
&
a
);
else
inlet_wrong
(
x
,
&
s_symbol
,
1
,
&
a
);
}
else
inlet_wrong
(
x
,
&
s_symbol
);
}
static
void
inlet_blob
(
t_inlet
*
x
,
t_blob
*
st
)
/* MP20061226 blob type */
...
...
@@ -152,7 +156,7 @@ static void inlet_blob(t_inlet *x, t_blob *st) /* MP20061226 blob type */
else
{
/*post("inlet_blob calling inlet_wrong");*/
inlet_wrong
(
x
,
&
s_blob
);
inlet_wrong
(
x
,
&
s_blob
,
0
,
0
);
}
}
...
...
@@ -168,7 +172,7 @@ static void inlet_list(t_inlet *x, t_symbol *s, int argc, t_atom *argv)
inlet_float
(
x
,
atom_getfloat
(
argv
));
else
if
(
argc
==
1
&&
argv
->
a_type
==
A_SYMBOL
)
inlet_symbol
(
x
,
atom_getsymbol
(
argv
));
else
inlet_wrong
(
x
,
&
s_list
);
else
inlet_wrong
(
x
,
&
s_list
,
0
,
0
);
}
static
void
inlet_anything
(
t_inlet
*
x
,
t_symbol
*
s
,
int
argc
,
t_atom
*
argv
)
...
...
@@ -177,7 +181,7 @@ static void inlet_anything(t_inlet *x, t_symbol *s, int argc, t_atom *argv)
typedmess
(
x
->
i_dest
,
x
->
i_symto
,
argc
,
argv
);
else
if
(
!
x
->
i_symfrom
)
typedmess
(
x
->
i_dest
,
s
,
argc
,
argv
);
else
inlet_wrong
(
x
,
s
);
else
inlet_wrong
(
x
,
s
,
0
,
0
);
}
void
inlet_free
(
t_inlet
*
x
)
...
...
pd/src/x_connective.c
View file @
11f6610d
...
...
@@ -8,6 +8,9 @@
#include
<string.h>
#include
<stdio.h>
#include
<stdlib.h>
#include
<errno.h>
extern
t_pd
*
newest
;
/* -------------------------- int ------------------------------ */
...
...
@@ -95,6 +98,59 @@ static void pdfloat_float(t_pdfloat *x, t_float f)
outlet_float
(
x
->
x_obj
.
ob_outlet
,
x
->
x_f
=
f
);
}
/* check if a symbol payload can be interpreted as a floating point number.
We get these cases sometimes from [makefilename], [keyname], and some
externals that shoot out data that would be parsed as a float if loaded
from a file.
return values are: 0 not a number
1 successfully parsed as float (stored in f)
if the number would underflow f is set to -1
if the number would overflow f is set to greater than zero
*/
int
symbol_can_float
(
t_symbol
*
s
,
t_float
*
f
)
{
int
ret
;
char
c
,
*
str_end
;
c
=
s
->
s_name
[
0
];
if
(
c
!=
'-'
&&
c
!=
'+'
&&
(
c
<
48
||
c
>
57
))
return
0
;
errno
=
0
;
*
f
=
strtod
(
s
->
s_name
,
&
str_end
);
if
(
errno
==
ERANGE
)
{
ret
=
0
;
if
(
*
f
==
0
)
*
f
=
-
1
;
/* underflow */
else
*
f
=
1
;
/* assume overflow otherwise */
}
else
if
(
*
f
==
0
&&
s
->
s_name
==
str_end
)
{
ret
=
0
;
}
else
ret
=
1
;
return
ret
;
}
char
*
type_hint
(
t_symbol
*
s
,
int
argc
,
t_atom
*
argv
,
int
check_symforfloat
);
static
void
pdfloat_symbol
(
t_pdfloat
*
x
,
t_symbol
*
s
)
{
t_float
f
=
0
;
if
(
symbol_can_float
(
s
,
&
f
))
outlet_float
(
x
->
x_obj
.
ob_outlet
,
x
->
x_f
=
f
);
else
{
t_atom
at
;
SETSYMBOL
(
&
at
,
s
);
pd_error
(
x
,
"couldn't convert 'symbol %s' to float%s"
,
s
->
s_name
,
f
==
-
1
?
" (number too small)"
:
f
==
1
?
" (number too large)"
:
type_hint
(
&
s_symbol
,
1
,
&
at
,
0
));
}
}
static
void
pdfloat_send
(
t_pdfloat
*
x
,
t_symbol
*
s
)
{
if
(
s
->
s_thing
)
...
...
@@ -111,6 +167,7 @@ void pdfloat_setup(void)
A_SYMBOL
,
0
);
class_addbang
(
pdfloat_class
,
pdfloat_bang
);
class_addfloat
(
pdfloat_class
,
(
t_method
)
pdfloat_float
);
class_addsymbol
(
pdfloat_class
,
(
t_method
)
pdfloat_symbol
);
}
/* -------------------------- symbol ------------------------------ */
...
...
scripts/regression_tests.pd
View file @
11f6610d
#N canvas
732 89
749 571 12;
#N canvas
340 105
749 571 12;
#X obj 465 281 r \$0-result;
#X obj 212 239 bng 31 250 50 0 empty empty Run_all 39 13 0 12 -262144
-1 -1;
...
...
@@ -25,7 +25,7 @@ is handy for some binbuf tests.;
#X obj 198 659 rtest makefilename_double_percent;
#X obj 198 710 rtest makefilename_code_coverage;
#N canvas 461 242 450 323 (subpatch) 0;
#X restore 201
199
5 pd;
#X restore 201
217
5 pd;
#X obj 198 761 rtest makefilename_default;
#X obj 198 812 rtest makefilename_default_bang;
#X obj 198 863 rtest makefilename_float;
...
...
@@ -55,6 +55,8 @@ is handy for some binbuf tests.;
#X obj 198 1811 rtest float_send_method;
#X obj 198 1866 rtest int_send_method;
#X obj 198 1921 rtest value_send_method;
#X obj 198 1976 rtest float_symbol_method;
#X obj 198 2031 rtest type_hint_coverage;
#X connect 0 0 27 0;
#X connect 1 0 4 0;
#X connect 2 0 42 0;
...
...
@@ -95,3 +97,5 @@ is handy for some binbuf tests.;
#X connect 46 0 47 0;
#X connect 47 0 48 0;
#X connect 48 0 49 0;
#X connect 49 0 50 0;
#X connect 50 0 51 0;
scripts/regression_tests/float_symbol_method.pd
0 → 100644
View file @
11f6610d
#N canvas 43 89 962 524 12;
#X obj 94 24 inlet;
#X obj 355 123 unpost;
#X obj 424 227 float;
#X obj 280 93 trigger bang bang bang;
#X obj 330 188 list;
#X obj 94 53 trigger bang bang;
#X obj 330 217 list length;
#X obj 238 258 symbol;
#X obj 169 193 unpost;
#X obj 238 297 float;
#X obj 94 163 trigger bang bang bang;
#X obj 144 258 list;
#X obj 144 287 list length;
#X obj 424 188 makefilename %d;
#X msg 424 158 42;
#X obj 330 279 list append sending a symbol message with a numeric
payload to [float] should trigger a conversion to float;
#X obj 144 329 list append sending a symbol message with a non-numeric
payload to [float] should cause an error;
#X obj 144 444 outlet;
#X obj 330 246 == 0;
#X connect 0 0 5 0;
#X connect 1 0 4 1;
#X connect 1 1 14 0;
#X connect 3 0 4 0;
#X connect 3 1 1 0;
#X connect 3 2 4 1;
#X connect 4 0 6 0;
#X connect 5 0 10 0;
#X connect 5 1 3 0;
#X connect 6 0 18 0;
#X connect 7 0 9 0;
#X connect 8 0 11 1;
#X connect 8 1 7 0;
#X connect 10 0 11 0;
#X connect 10 1 8 0;
#X connect 10 2 11 1;
#X connect 11 0 12 0;
#X connect 12 0 16 0;
#X connect 13 0 2 0;
#X connect 14 0 13 0;
#X connect 15 0 17 0;
#X connect 16 0 17 0;
#X connect 18 0 15 0;
scripts/regression_tests/type_hint_coverage.pd
0 → 100644
View file @
11f6610d
#N canvas 2 79 1230 587 12;
#X obj 128 68 inlet;
#X obj 244 127 unpost;
#X text 230 26 trigger as many branches as we can from the patch for
the type hints that come with certain errors. Just looking for crashers
here \, but we can later expand these if we wish.;
#X obj 128 486 list append triggered type hints and nothing crashed.
Hooray!;
#X obj 128 97 trigger bang bang;
#X obj 128 127 f 1;
#X obj 728 288 list trim;
#X msg 696 218 symbol;
#X obj 696 247 t a a;
#X text 755 219 empty symbol message;
#X text 805 289 empty symbol atom as selector;
#X msg 574 218 1;
#X obj 574 247 makefilename %d;
#X text 580 278 symbol message;
#X text 580 298 with "floatlike";
#X text 580 318 symbol atom;
#X text 580 338 payload;
#X obj 424 247 makefilename 1e+%d;
#X msg 424 218 2048;
#X msg 284 218 2048;
#X obj 284 247 makefilename 1e-%d;
#X obj 424 346 t a a;
#X obj 424 385 list trim;
#X obj 283 154 trigger bang bang bang bang;
#X text 283 286 symbol atoms with "floatlike" payload;
#X text 283 306 tht is out of range;
#X obj 128 531 outlet;
#X obj 696 430 trigger anything anything;
#X obj 696 499 int;
#X text 735 471 run through the inlet class \, too;
#X connect 0 0 4 0;
#X connect 1 1 23 0;
#X connect 3 0 26 0;
#X connect 4 0 5 0;
#X connect 4 1 1 0;
#X connect 5 0 3 0;
#X connect 6 0 27 0;
#X connect 7 0 8 0;
#X connect 8 0 27 0;
#X connect 8 1 6 0;
#X connect 11 0 12 0;
#X connect 12 0 27 0;
#X connect 17 0 21 0;
#X connect 18 0 17 0;
#X connect 19 0 20 0;
#X connect 20 0 21 0;
#X connect 21 0 22 0;
#X connect 21 1 27 0;
#X connect 22 0 27 0;
#X connect 23 0 19 0;
#X connect 23 1 18 0;
#X connect 23 2 11 0;
#X connect 23 3 7 0;
#X connect 27 0 28 0;
#X connect 27 1 28 1;
Albert Gräf
@aggraef
mentioned in issue
#660 (closed)
·
Jul 10, 2020
mentioned in issue
#660 (closed)
mentioned in issue #660
Toggle commit list
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment