1 /* Copyright (c) 1997-1999 Miller Puckette.
2 * For information on usage and redistribution, and for a DISCLAIMER OF ALL
3 * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
7 * changed the canvas_restore in "g_canvas.c", so that it might accept $args as well (like "pd $0_test")
8 * so you can make multiple & distinguishable templates
9 * 1511:forum::für::umläute:2001
10 * change marked with IOhannes
15 #include "../../pdbox.h"
17 int printf(const char *fmt
, ...);
18 void perror(const char*);
44 t_binbuf
*binbuf_new(void)
46 t_binbuf
*x
= (t_binbuf
*)t_getbytes(sizeof(*x
));
48 x
->b_vec
= t_getbytes(0);
52 void binbuf_free(t_binbuf
*x
)
54 t_freebytes(x
->b_vec
, x
->b_n
* sizeof(*x
->b_vec
));
55 t_freebytes(x
, sizeof(*x
));
58 t_binbuf
*binbuf_duplicate(t_binbuf
*y
)
60 t_binbuf
*x
= (t_binbuf
*)t_getbytes(sizeof(*x
));
62 x
->b_vec
= t_getbytes(x
->b_n
* sizeof(*x
->b_vec
));
63 memcpy(x
->b_vec
, y
->b_vec
, x
->b_n
* sizeof(*x
->b_vec
));
67 void binbuf_clear(t_binbuf
*x
)
69 x
->b_vec
= t_resizebytes(x
->b_vec
, x
->b_n
* sizeof(*x
->b_vec
), 0);
73 /* convert text to a binbuf */
74 void binbuf_text(t_binbuf
*x
, char *text
, size_t size
)
76 char buf
[MAXPDSTRING
+1], *bufp
, *ebuf
= buf
+MAXPDSTRING
;
77 const char *textp
= text
, *etext
= text
+size
;
79 int nalloc
= 16, natom
= 0;
80 t_freebytes(x
->b_vec
, x
->b_n
* sizeof(*x
->b_vec
));
81 x
->b_vec
= t_getbytes(nalloc
* sizeof(*x
->b_vec
));
89 /* skip leading space */
90 while ((textp
!= etext
) && (*textp
== ' ' || *textp
== '\n'
91 || *textp
== '\r' || *textp
== '\t')) textp
++;
92 if (textp
== etext
) break;
93 if (*textp
== ';') SETSEMI(ap
), textp
++;
94 else if (*textp
== ',') SETCOMMA(ap
), textp
++;
97 /* it's an atom other than a comma or semi */
99 int floatstate
= 0, slash
= 0, lastslash
= 0,
100 firstslash
= (*textp
== '\\');
104 c
= *bufp
= *textp
++;
110 int digit
= (c
>= '0' && c
<= '9'),
111 dot
= (c
== '.'), minus
= (c
== '-'),
112 plusminus
= (minus
|| (c
== '+')),
113 expon
= (c
== 'e' || c
== 'E');
114 if (floatstate
== 0) /* beginning */
116 if (minus
) floatstate
= 1;
117 else if (digit
) floatstate
= 2;
118 else if (dot
) floatstate
= 3;
119 else floatstate
= -1;
121 else if (floatstate
== 1) /* got minus */
123 if (digit
) floatstate
= 2;
124 else if (dot
) floatstate
= 3;
125 else floatstate
= -1;
127 else if (floatstate
== 2) /* got digits */
129 if (dot
) floatstate
= 4;
130 else if (expon
) floatstate
= 6;
131 else if (!digit
) floatstate
= -1;
133 else if (floatstate
== 3) /* got '.' without digits */
135 if (digit
) floatstate
= 5;
136 else floatstate
= -1;
138 else if (floatstate
== 4) /* got '.' after digits */
140 if (digit
) floatstate
= 5;
141 else if (expon
) floatstate
= 6;
142 else floatstate
= -1;
144 else if (floatstate
== 5) /* got digits after . */
146 if (expon
) floatstate
= 6;
147 else if (!digit
) floatstate
= -1;
149 else if (floatstate
== 6) /* got 'e' */
151 if (plusminus
) floatstate
= 7;
152 else if (digit
) floatstate
= 8;
153 else floatstate
= -1;
155 else if (floatstate
== 7) /* got plus or minus */
157 if (digit
) floatstate
= 8;
158 else floatstate
= -1;
160 else if (floatstate
== 8) /* got digits */
162 if (!digit
) floatstate
= -1;
167 while (textp
!= etext
&& bufp
!= ebuf
&&
168 (slash
|| (*textp
!= ' ' && *textp
!= '\n' && *textp
!= '\r'
169 && *textp
!= '\t' &&*textp
!= ',' && *textp
!= ';')));
175 if (*buf
== '$' && buf
[1] >= '0' && buf
[1] <= '9' && !firstslash
)
177 for (bufp
= buf
+2; *bufp
; bufp
++)
178 if (*bufp
< '0' || *bufp
> '9')
180 SETDOLLSYM(ap
, gensym(buf
+1));
183 SETDOLLAR(ap
, atoi(buf
+1));
188 if (floatstate
== 2 || floatstate
== 4 || floatstate
== 5 ||
190 SETFLOAT(ap
, atof(buf
));
191 else SETSYMBOL(ap
, gensym(buf
));
198 x
->b_vec
= t_resizebytes(x
->b_vec
, nalloc
* sizeof(*x
->b_vec
),
199 nalloc
* (2*sizeof(*x
->b_vec
)));
201 ap
= x
->b_vec
+ natom
;
203 if (textp
== etext
) break;
205 /* reallocate the vector to exactly the right size */
206 x
->b_vec
= t_resizebytes(x
->b_vec
, nalloc
* sizeof(*x
->b_vec
),
207 natom
* sizeof(*x
->b_vec
));
211 /* convert a binbuf to text; no null termination. */
212 void binbuf_gettext(t_binbuf
*x
, char **bufp
, int *lengthp
)
214 char *buf
= getbytes(0), *newbuf
;
216 char string
[MAXPDSTRING
];
220 for (ap
= x
->b_vec
, indx
= x
->b_n
; indx
--; ap
++)
223 if ((ap
->a_type
== A_SEMI
|| ap
->a_type
== A_COMMA
) &&
224 length
&& buf
[length
-1] == ' ') length
--;
225 atom_string(ap
, string
, MAXPDSTRING
);
226 newlength
= length
+ strlen(string
) + 1;
227 if (!(newbuf
= resizebytes(buf
, length
, newlength
))) break;
229 strcpy(buf
+ length
, string
);
231 if (ap
->a_type
== A_SEMI
) buf
[length
-1] = '\n';
232 else buf
[length
-1] = ' ';
234 if (length
&& buf
[length
-1] == ' ')
236 if((newbuf
= t_resizebytes(buf
, length
, length
-1)))
246 /* LATER improve the out-of-space behavior below. Also fix this so that
247 writing to file doesn't buffer everything together. */
249 void binbuf_add(t_binbuf
*x
, int argc
, t_atom
*argv
)
251 int newsize
= x
->b_n
+ argc
, i
;
253 if((ap
= t_resizebytes(x
->b_vec
, x
->b_n
* sizeof(*x
->b_vec
),
254 newsize
* sizeof(*x
->b_vec
))))
258 error("binbuf_addmessage: out of space");
262 startpost("binbuf_add: ");
263 postatom(argc
, argv
);
266 for (ap
= x
->b_vec
+ x
->b_n
, i
= argc
; i
--; ap
++)
271 #define MAXADDMESSV 100
272 void binbuf_addv(t_binbuf
*x
, char *fmt
, ...)
275 t_atom arg
[MAXADDMESSV
], *at
=arg
;
282 if (nargs
>= MAXADDMESSV
)
284 error("binbuf_addmessv: only %d allowed", MAXADDMESSV
);
289 case 'i': SETFLOAT(at
, va_arg(ap
, t_int
)); break;
290 case 'f': SETFLOAT(at
, va_arg(ap
, double)); break;
291 case 's': SETSYMBOL(at
, va_arg(ap
, t_symbol
*)); break;
292 case ';': SETSEMI(at
); break;
293 case ',': SETCOMMA(at
); break;
301 binbuf_add(x
, nargs
, arg
);
304 /* add a binbuf to another one for saving. Semicolons and commas go to
305 symbols ";", "'",; the symbol ";" goes to "\;", etc. */
307 void binbuf_addbinbuf(t_binbuf
*x
, t_binbuf
*y
)
309 t_binbuf
*z
= binbuf_new();
312 binbuf_add(z
, y
->b_n
, y
->b_vec
);
313 for (i
= 0, ap
= z
->b_vec
; i
< z
->b_n
; i
++, ap
++)
315 char tbuf
[MAXPDSTRING
];
321 SETSYMBOL(ap
, gensym(";"));
324 SETSYMBOL(ap
, gensym(","));
328 snprintf(tbuf
, sizeof(tbuf
), "$%d", ap
->a_w
.w_index
);
330 sprintf(tbuf
, "$%d", ap
->a_w
.w_index
);
332 SETSYMBOL(ap
, gensym(tbuf
));
336 snprintf(tbuf
, sizeof(tbuf
), "$%s", ap
->a_w
.w_symbol
->s_name
);
338 sprintf(tbuf
, "$%s", ap
->a_w
.w_symbol
->s_name
);
340 SETSYMBOL(ap
, gensym(tbuf
));
343 /* FIXME make this general */
344 if (!strcmp(ap
->a_w
.w_symbol
->s_name
, ";"))
345 SETSYMBOL(ap
, gensym(";"));
346 else if (!strcmp(ap
->a_w
.w_symbol
->s_name
, ","))
347 SETSYMBOL(ap
, gensym(","));
350 bug("binbuf_addbinbuf");
354 binbuf_add(x
, z
->b_n
, z
->b_vec
);
357 void binbuf_addsemi(t_binbuf
*x
)
361 binbuf_add(x
, 1, &a
);
364 /* Supply atoms to a binbuf from a message, making the opposite changes
365 from binbuf_addbinbuf. The symbol ";" goes to a semicolon, etc. */
367 void binbuf_restore(t_binbuf
*x
, int argc
, t_atom
*argv
)
369 int newsize
= x
->b_n
+ argc
, i
;
371 if((ap
= t_resizebytes(x
->b_vec
, x
->b_n
* sizeof(*x
->b_vec
),
372 newsize
* sizeof(*x
->b_vec
))))
376 error("binbuf_addmessage: out of space");
380 for (ap
= x
->b_vec
+ x
->b_n
, i
= argc
; i
--; ap
++)
382 if (argv
->a_type
== A_SYMBOL
)
384 char *str
= argv
->a_w
.w_symbol
->s_name
;
385 if (!strcmp(str
, ";")) SETSEMI(ap
);
386 else if (!strcmp(str
, ",")) SETCOMMA(ap
);
387 else if (str
[0] == '$' && str
[1] >= '0' && str
[1] <= '9')
391 for (str2
= str
+ 2; *str2
; str2
++)
392 if (*str2
< '0' || *str2
> '9')
395 SETDOLLSYM(ap
, gensym(str
+ 1));
400 dollar
= atoi(argv
->a_w
.w_symbol
->s_name
+ 1);
402 sscanf(argv
->a_w
.w_symbol
->s_name
+ 1, "%d", &dollar
);
404 SETDOLLAR(ap
, dollar
);
410 else *ap
= *(argv
++);
416 #define MSTACKSIZE 2048
418 void binbuf_print(t_binbuf
*x
)
420 int i
, startedpost
= 0, newline
= 1;
421 for (i
= 0; i
< x
->b_n
; i
++)
425 if (startedpost
) endpost();
429 postatom(1, x
->b_vec
+ i
);
430 if (x
->b_vec
[i
].a_type
== A_SEMI
)
434 if (startedpost
) endpost();
437 int binbuf_getnatom(t_binbuf
*x
)
442 t_atom
*binbuf_getvec(t_binbuf
*x
)
447 int canvas_getdollarzero( void);
449 t_symbol
*binbuf_realizedollsym(t_symbol
*s
, int ac
, t_atom
*av
, int tonew
)
451 int argno
= atol(s
->s_name
), lastnum
;
452 char buf
[MAXPDSTRING
], c
, *sp
;
453 for (lastnum
= 0, sp
= s
->s_name
; ((c
= *sp
) && c
>= '0' && c
<= '9');
455 if (!c
|| argno
< 0 || argno
> ac
)
460 else snprintf(buf
, sizeof(buf
), "$%d", argno
);
462 else sprintf(buf
, "$%d", argno
);
467 snprintf(buf
, sizeof(buf
), "%d", canvas_getdollarzero());
469 sprintf(buf
, "%d", canvas_getdollarzero());
472 atom_string(av
+(argno
-1), buf
, MAXPDSTRING
/2-1);
473 strncat(buf
, sp
, MAXPDSTRING
/2-1);
474 return (gensym(buf
));
477 void binbuf_eval(t_binbuf
*x
, t_pd
*target
, int argc
, t_atom
*argv
)
479 static t_atom mstack
[MSTACKSIZE
], *msp
= mstack
, *ems
= mstack
+MSTACKSIZE
;
480 t_atom
*stackwas
= msp
;
481 t_atom
*at
= x
->b_vec
;
491 while (ac
&& (at
->a_type
== A_SEMI
|| at
->a_type
== A_COMMA
))
494 if (at
->a_type
== A_DOLLAR
)
496 if (at
->a_w
.w_index
<= 0 || at
->a_w
.w_index
> argc
)
498 error("$%d: not enough arguments supplied",
502 else if (argv
[at
->a_w
.w_index
-1].a_type
!= A_SYMBOL
)
504 error("$%d: symbol needed as message destination",
508 else s
= argv
[at
->a_w
.w_index
-1].a_w
.w_symbol
;
510 else if (at
->a_type
== A_DOLLSYM
)
512 if (!(s
= binbuf_realizedollsym(at
->a_w
.w_symbol
,
515 error("$%s: not enough arguments supplied",
516 at
->a_w
.w_symbol
->s_name
);
520 else s
= atom_getsymbol(at
);
521 if (!(target
= s
->s_thing
))
523 error("%s: no such object", s
->s_name
);
526 while (ac
&& at
->a_type
!= A_SEMI
);
527 /* LATER eat args until semicolon and continue */
542 if (!ac
) goto gotmess
;
545 error("message stack overflow");
551 /* semis and commas in new message just get bashed to
552 a symbol. This is needed so you can pass them to "expr." */
553 if (target
== &pd_objectmaker
)
555 SETSYMBOL(msp
, gensym(";"));
564 if (target
== &pd_objectmaker
)
566 SETSYMBOL(msp
, gensym(","));
575 if (at
->a_w
.w_index
> 0 && at
->a_w
.w_index
<= argc
)
576 *msp
= argv
[at
->a_w
.w_index
-1];
577 else if (at
->a_w
.w_index
== 0)
578 SETFLOAT(msp
, canvas_getdollarzero());
581 if (target
== &pd_objectmaker
)
585 error("$%d: argument number out of range",
592 s9
= binbuf_realizedollsym(at
->a_w
.w_symbol
, argc
, argv
,
593 target
== &pd_objectmaker
);
599 bug("bad item in binbuf");
610 switch (stackwas
->a_type
)
613 typedmess(target
, stackwas
->a_w
.w_symbol
, nargs
-1, stackwas
+1);
616 if (nargs
== 1) pd_float(target
, stackwas
->a_w
.w_float
);
617 else pd_list(target
, 0, nargs
, stackwas
);
637 static int binbuf_doopen(char *s
, int mode
)
639 char namebuf
[MAXPDSTRING
];
643 sys_bashfilename(s
, namebuf
);
644 return (open(namebuf
, mode
));
648 static FILE *binbuf_dofopen(char *s
, char *mode
)
650 char namebuf
[MAXPDSTRING
];
651 sys_bashfilename(s
, namebuf
);
652 return (fopen(namebuf
, mode
));
656 int binbuf_read(t_binbuf
*b
, char *filename
, char *dirname
, int crflag
)
662 char namebuf
[MAXPDSTRING
];
666 strcat(namebuf
, dirname
), strcat(namebuf
, "/");
667 strcat(namebuf
, filename
);
669 if ((fd
= binbuf_doopen(namebuf
, 0)) < 0)
675 #endif /* SIMULATOR */
677 fprintf(stderr
, "open: ");
682 if ((length
= lseek(fd
, 0, SEEK_END
)) < 0 || lseek(fd
, 0, SEEK_SET
) < 0
683 || !(buf
= t_getbytes(length
)))
689 #endif /* SIMULATOR */
691 fprintf(stderr
, "lseek: ");
697 if ((readret
= read(fd
, buf
, length
)) < length
)
701 printf("read (%d %ld) -> %d\n", fd
, length
, readret
);
703 #endif /* SIMULATOR */
705 fprintf(stderr
, "read (%d %ld) -> %d\n", fd
, length
, readret
);
709 t_freebytes(buf
, length
);
712 /* optionally map carriage return to semicolon */
716 for (i
= 0; i
< length
; i
++)
720 binbuf_text(b
, buf
, length
);
723 startpost("binbuf_read "); postatom(b
->b_n
, b
->b_vec
); endpost();
726 t_freebytes(buf
, length
);
731 int binbuf_read_via_path(t_binbuf
*b
, char *filename
, char *dirname
,
735 char buf
[MAXPDSTRING
], *bufptr
;
736 if ((filedesc
= open_via_path(
737 dirname
, filename
, "", buf
, &bufptr
, MAXPDSTRING
, 0)) < 0)
739 error("%s: can't open", filename
);
742 else close (filedesc
);
743 if (binbuf_read(b
, bufptr
, buf
, crflag
))
748 #define WBUFSIZE 4096
749 static t_binbuf
*binbuf_convert(t_binbuf
*oldb
, int maxtopd
);
751 /* write a binbuf to a text file. If "crflag" is set we suppress
753 int binbuf_write(t_binbuf
*x
, char *filename
, char *dir
, int crflag
)
760 char sbuf
[WBUFSIZE
], fbuf
[MAXPDSTRING
], *bp
= sbuf
, *ep
= sbuf
+ WBUFSIZE
;
762 int indx
, deleteit
= 0;
767 strcat(fbuf
, dir
), strcat(fbuf
, "/");
768 strcat(fbuf
, filename
);
769 if (!strcmp(filename
+ strlen(filename
) - 4, ".pat"))
771 x
= binbuf_convert(x
, 0);
776 if(!(f
= binbuf_doopen(fbuf
, O_WRONLY
|O_CREAT
|O_TRUNC
)))
778 if (!(f
= binbuf_dofopen(fbuf
, "w")))
784 #endif /* SIMULATOR */
786 fprintf(stderr
, "open: ");
791 for (ap
= x
->b_vec
, indx
= x
->b_n
; indx
--; ap
++)
794 /* estimate how many characters will be needed. Printing out
795 symbols may need extra characters for inserting backslashes. */
796 if (ap
->a_type
== A_SYMBOL
|| ap
->a_type
== A_DOLLSYM
)
797 length
= 80 + strlen(ap
->a_w
.w_symbol
->s_name
);
799 if (ep
- bp
< length
)
802 if(write(f
, sbuf
, bp
-sbuf
) < 1)
804 if (fwrite(sbuf
, bp
-sbuf
, 1, f
) < 1)
812 if ((ap
->a_type
== A_SEMI
|| ap
->a_type
== A_COMMA
) &&
813 bp
> sbuf
&& bp
[-1] == ' ') bp
--;
814 if (!crflag
|| ap
->a_type
!= A_SEMI
)
816 atom_string(ap
, bp
, (ep
-bp
)-2);
821 if (ap
->a_type
== A_SEMI
|| (!crflag
&& ncolumn
> 65))
833 if(write(f
, sbuf
, bp
-sbuf
) < 1)
835 if (fwrite(sbuf
, bp
-sbuf
, 1, f
) < 1)
861 /* The following routine attempts to convert from max to pd or back. The
862 max to pd direction is working OK but you will need to make lots of
863 abstractions for objects like "gate" which don't exist in Pd. conversion
864 from Pd to Max hasn't been tested for patches with subpatches yet! */
866 #define MAXSTACK 1000
868 #define ISSYMBOL(a, b) ((a)->a_type == A_SYMBOL && \
869 !strcmp((a)->a_w.w_symbol->s_name, (b)))
871 static t_binbuf
*binbuf_convert(t_binbuf
*oldb
, int maxtopd
)
873 t_binbuf
*newb
= binbuf_new();
874 t_atom
*vec
= oldb
->b_vec
;
875 t_int n
= oldb
->b_n
, nextindex
, stackdepth
= 0, stack
[MAXSTACK
],
877 t_atom outmess
[MAXSTACK
], *nextmess
;
879 binbuf_addv(newb
, "ss;", gensym("max"), gensym("v2"));
880 for (nextindex
= 0; nextindex
< n
; )
883 char *first
, *second
;
884 for (endmess
= nextindex
; endmess
< n
&& vec
[endmess
].a_type
!= A_SEMI
;
887 if (endmess
== n
) break;
888 if (endmess
== nextindex
|| endmess
== nextindex
+ 1
889 || vec
[nextindex
].a_type
!= A_SYMBOL
||
890 vec
[nextindex
+1].a_type
!= A_SYMBOL
)
892 nextindex
= endmess
+ 1;
895 natom
= endmess
- nextindex
;
896 if (natom
> MAXSTACK
-10) natom
= MAXSTACK
-10;
897 nextmess
= vec
+ nextindex
;
898 first
= nextmess
->a_w
.w_symbol
->s_name
;
899 second
= (nextmess
+1)->a_w
.w_symbol
->s_name
;
902 /* case 1: importing a ".pat" file into Pd. */
904 /* dollar signs in file translate to symbols */
905 for (i
= 0; i
< natom
; i
++)
907 if (nextmess
[i
].a_type
== A_DOLLAR
)
911 snprintf(buf
, sizeof(buf
), "$%d", nextmess
[i
].a_w
.w_index
);
913 sprintf(buf
, "$%d", nextmess
[i
].a_w
.w_index
);
915 SETSYMBOL(nextmess
+i
, gensym(buf
));
917 else if (nextmess
[i
].a_type
== A_DOLLSYM
)
921 snprintf(buf
, sizeof(buf
), "$%s", nextmess
[i
].a_w
.w_symbol
->s_name
);
923 sprintf(buf
, "$%s", nextmess
[i
].a_w
.w_symbol
->s_name
);
925 SETSYMBOL(nextmess
+i
, gensym(buf
));
928 if (!strcmp(first
, "#N"))
930 if (!strcmp(second
, "vpatcher"))
932 if (stackdepth
>= MAXSTACK
)
934 post("too many embedded patches");
937 stack
[stackdepth
] = nobj
;
940 binbuf_addv(newb
, "ssfffff;",
941 gensym("#N"), gensym("canvas"),
942 atom_getfloatarg(2, natom
, nextmess
),
943 atom_getfloatarg(3, natom
, nextmess
),
944 atom_getfloatarg(4, natom
, nextmess
) -
945 atom_getfloatarg(2, natom
, nextmess
),
946 atom_getfloatarg(5, natom
, nextmess
) -
947 atom_getfloatarg(3, natom
, nextmess
),
951 (float)sys_defaultfont
);
955 if (!strcmp(first
, "#P"))
957 /* drop initial "hidden" flag */
958 if (!strcmp(second
, "hidden"))
962 second
= (nextmess
+1)->a_w
.w_symbol
->s_name
;
964 if (natom
>= 7 && !strcmp(second
, "newobj")
965 && (ISSYMBOL(&nextmess
[6], "patcher") ||
966 ISSYMBOL(&nextmess
[6], "p")))
968 binbuf_addv(newb
, "ssffss;",
969 gensym("#X"), gensym("restore"),
970 atom_getfloatarg(2, natom
, nextmess
),
971 atom_getfloatarg(3, natom
, nextmess
),
972 gensym("pd"), atom_getsymbolarg(7, natom
, nextmess
));
973 if (stackdepth
) stackdepth
--;
974 nobj
= stack
[stackdepth
];
977 else if (!strcmp(second
, "newex") || !strcmp(second
, "newobj"))
979 t_symbol
*classname
=
980 atom_getsymbolarg(6, natom
, nextmess
);
981 if (classname
== gensym("trigger") ||
982 classname
== gensym("t"))
984 for (i
= 7; i
< natom
; i
++)
985 if (nextmess
[i
].a_type
== A_SYMBOL
&&
986 nextmess
[i
].a_w
.w_symbol
== gensym("i"))
987 nextmess
[i
].a_w
.w_symbol
= gensym("f");
989 if (classname
== gensym("table"))
990 classname
= gensym("TABLE");
991 SETSYMBOL(outmess
, gensym("#X"));
992 SETSYMBOL(outmess
+ 1, gensym("obj"));
993 outmess
[2] = nextmess
[2];
994 outmess
[3] = nextmess
[3];
995 SETSYMBOL(outmess
+4, classname
);
996 for (i
= 7; i
< natom
; i
++)
997 outmess
[i
-2] = nextmess
[i
];
998 SETSEMI(outmess
+ natom
- 2);
999 binbuf_add(newb
, natom
- 1, outmess
);
1002 else if (!strcmp(second
, "message") ||
1003 !strcmp(second
, "comment"))
1005 SETSYMBOL(outmess
, gensym("#X"));
1006 SETSYMBOL(outmess
+ 1, gensym(
1007 (strcmp(second
, "message") ? "text" : "msg")));
1008 outmess
[2] = nextmess
[2];
1009 outmess
[3] = nextmess
[3];
1010 for (i
= 6; i
< natom
; i
++)
1011 outmess
[i
-2] = nextmess
[i
];
1012 SETSEMI(outmess
+ natom
- 2);
1013 binbuf_add(newb
, natom
- 1, outmess
);
1016 else if (!strcmp(second
, "button"))
1018 binbuf_addv(newb
, "ssffs;",
1019 gensym("#X"), gensym("obj"),
1020 atom_getfloatarg(2, natom
, nextmess
),
1021 atom_getfloatarg(3, natom
, nextmess
),
1025 else if (!strcmp(second
, "number") || !strcmp(second
, "flonum"))
1027 binbuf_addv(newb
, "ssff;",
1028 gensym("#X"), gensym("floatatom"),
1029 atom_getfloatarg(2, natom
, nextmess
),
1030 atom_getfloatarg(3, natom
, nextmess
));
1033 else if (!strcmp(second
, "slider"))
1035 float inc
= atom_getfloatarg(7, natom
, nextmess
);
1038 binbuf_addv(newb
, "ssffsffffffsssfffffffff;",
1039 gensym("#X"), gensym("obj"),
1040 atom_getfloatarg(2, natom
, nextmess
),
1041 atom_getfloatarg(3, natom
, nextmess
),
1043 atom_getfloatarg(4, natom
, nextmess
),
1044 atom_getfloatarg(5, natom
, nextmess
),
1045 atom_getfloatarg(6, natom
, nextmess
),
1046 atom_getfloatarg(6, natom
, nextmess
)
1047 + (atom_getfloatarg(5, natom
, nextmess
) - 1) * inc
,
1049 gensym("empty"), gensym("empty"), gensym("empty"),
1050 0., -8., 0., 8., -262144., -1., -1., 0., 1.);
1053 else if (!strcmp(second
, "toggle"))
1055 binbuf_addv(newb
, "ssffs;",
1056 gensym("#X"), gensym("obj"),
1057 atom_getfloatarg(2, natom
, nextmess
),
1058 atom_getfloatarg(3, natom
, nextmess
),
1062 else if (!strcmp(second
, "inlet"))
1064 binbuf_addv(newb
, "ssffs;",
1065 gensym("#X"), gensym("obj"),
1066 atom_getfloatarg(2, natom
, nextmess
),
1067 atom_getfloatarg(3, natom
, nextmess
),
1068 gensym((natom
> 5 ? "inlet~" : "inlet")));
1071 else if (!strcmp(second
, "outlet"))
1073 binbuf_addv(newb
, "ssffs;",
1074 gensym("#X"), gensym("obj"),
1075 atom_getfloatarg(2, natom
, nextmess
),
1076 atom_getfloatarg(3, natom
, nextmess
),
1077 gensym((natom
> 5 ? "outlet~" : "outlet")));
1080 else if (!strcmp(second
, "user"))
1082 binbuf_addv(newb
, "ssffs;",
1083 gensym("#X"), gensym("obj"),
1084 atom_getfloatarg(3, natom
, nextmess
),
1085 atom_getfloatarg(4, natom
, nextmess
),
1086 atom_getsymbolarg(2, natom
, nextmess
));
1089 else if (!strcmp(second
, "connect")||
1090 !strcmp(second
, "fasten"))
1092 binbuf_addv(newb
, "ssffff;",
1093 gensym("#X"), gensym("connect"),
1094 nobj
- atom_getfloatarg(2, natom
, nextmess
) - 1,
1095 atom_getfloatarg(3, natom
, nextmess
),
1096 nobj
- atom_getfloatarg(4, natom
, nextmess
) - 1,
1097 atom_getfloatarg(5, natom
, nextmess
));
1101 else /* Pd to Max */
1103 if (!strcmp(first
, "#N"))
1105 if (!strcmp(second
, "canvas"))
1107 if (stackdepth
>= MAXSTACK
)
1109 post("too many embedded patches");
1112 stack
[stackdepth
] = nobj
;
1115 binbuf_addv(newb
, "ssffff;",
1116 gensym("#N"), gensym("vpatcher"),
1117 atom_getfloatarg(2, natom
, nextmess
),
1118 atom_getfloatarg(3, natom
, nextmess
),
1119 atom_getfloatarg(4, natom
, nextmess
),
1120 atom_getfloatarg(5, natom
, nextmess
));
1123 if (!strcmp(first
, "#X"))
1125 if (natom
>= 5 && !strcmp(second
, "restore")
1126 && (ISSYMBOL (&nextmess
[4], "pd")))
1128 binbuf_addv(newb
, "ss;", gensym("#P"), gensym("pop"));
1129 binbuf_addv(newb
, "ssffffss;",
1130 gensym("#P"), gensym("newobj"),
1131 atom_getfloatarg(2, natom
, nextmess
),
1132 atom_getfloatarg(3, natom
, nextmess
), 50., 1.,
1134 atom_getsymbolarg(5, natom
, nextmess
));
1135 if (stackdepth
) stackdepth
--;
1136 nobj
= stack
[stackdepth
];
1139 else if (!strcmp(second
, "obj"))
1141 t_symbol
*classname
=
1142 atom_getsymbolarg(4, natom
, nextmess
);
1143 if (classname
== gensym("inlet"))
1144 binbuf_addv(newb
, "ssfff;", gensym("#P"),
1146 atom_getfloatarg(2, natom
, nextmess
),
1147 atom_getfloatarg(3, natom
, nextmess
),
1149 else if (classname
== gensym("inlet~"))
1150 binbuf_addv(newb
, "ssffff;", gensym("#P"),
1152 atom_getfloatarg(2, natom
, nextmess
),
1153 atom_getfloatarg(3, natom
, nextmess
),
1155 else if (classname
== gensym("outlet"))
1156 binbuf_addv(newb
, "ssfff;", gensym("#P"),
1158 atom_getfloatarg(2, natom
, nextmess
),
1159 atom_getfloatarg(3, natom
, nextmess
),
1161 else if (classname
== gensym("outlet~"))
1162 binbuf_addv(newb
, "ssffff;", gensym("#P"),
1164 atom_getfloatarg(2, natom
, nextmess
),
1165 atom_getfloatarg(3, natom
, nextmess
),
1167 else if (classname
== gensym("bng"))
1168 binbuf_addv(newb
, "ssffff;", gensym("#P"),
1170 atom_getfloatarg(2, natom
, nextmess
),
1171 atom_getfloatarg(3, natom
, nextmess
),
1172 atom_getfloatarg(5, natom
, nextmess
), 0.);
1173 else if (classname
== gensym("tgl"))
1174 binbuf_addv(newb
, "ssffff;", gensym("#P"),
1176 atom_getfloatarg(2, natom
, nextmess
),
1177 atom_getfloatarg(3, natom
, nextmess
),
1178 atom_getfloatarg(5, natom
, nextmess
), 0.);
1179 else if (classname
== gensym("vsl"))
1180 binbuf_addv(newb
, "ssffffff;", gensym("#P"),
1182 atom_getfloatarg(2, natom
, nextmess
),
1183 atom_getfloatarg(3, natom
, nextmess
),
1184 atom_getfloatarg(5, natom
, nextmess
),
1185 atom_getfloatarg(6, natom
, nextmess
),
1186 (atom_getfloatarg(8, natom
, nextmess
) -
1187 atom_getfloatarg(7, natom
, nextmess
)) /
1188 (atom_getfloatarg(6, natom
, nextmess
) == 1? 1 :
1189 atom_getfloatarg(6, natom
, nextmess
) - 1),
1190 atom_getfloatarg(7, natom
, nextmess
));
1193 SETSYMBOL(outmess
, gensym("#P"));
1194 SETSYMBOL(outmess
+ 1, gensym("newex"));
1195 outmess
[2] = nextmess
[2];
1196 outmess
[3] = nextmess
[3];
1197 SETFLOAT(outmess
+ 4, 50);
1198 SETFLOAT(outmess
+ 5, 1);
1199 for (i
= 4; i
< natom
; i
++)
1200 outmess
[i
+2] = nextmess
[i
];
1201 SETSEMI(outmess
+ natom
+ 2);
1202 binbuf_add(newb
, natom
+ 3, outmess
);
1207 else if (!strcmp(second
, "msg") ||
1208 !strcmp(second
, "text"))
1210 SETSYMBOL(outmess
, gensym("#P"));
1211 SETSYMBOL(outmess
+ 1, gensym(
1212 (strcmp(second
, "msg") ? "comment" : "message")));
1213 outmess
[2] = nextmess
[2];
1214 outmess
[3] = nextmess
[3];
1215 SETFLOAT(outmess
+ 4, 50);
1216 SETFLOAT(outmess
+ 5, 1);
1217 for (i
= 4; i
< natom
; i
++)
1218 outmess
[i
+2] = nextmess
[i
];
1219 SETSEMI(outmess
+ natom
+ 2);
1220 binbuf_add(newb
, natom
+ 3, outmess
);
1223 else if (!strcmp(second
, "floatatom"))
1225 binbuf_addv(newb
, "ssfff;",
1226 gensym("#P"), gensym("flonum"),
1227 atom_getfloatarg(2, natom
, nextmess
),
1228 atom_getfloatarg(3, natom
, nextmess
), 35);
1231 else if (!strcmp(second
, "connect"))
1233 binbuf_addv(newb
, "ssffff;",
1234 gensym("#P"), gensym("connect"),
1235 nobj
- atom_getfloatarg(2, natom
, nextmess
) - 1,
1236 atom_getfloatarg(3, natom
, nextmess
),
1237 nobj
- atom_getfloatarg(4, natom
, nextmess
) - 1,
1238 atom_getfloatarg(5, natom
, nextmess
));
1242 nextindex
= endmess
+ 1;
1245 binbuf_addv(newb
, "ss;", gensym("#P"), gensym("pop"));
1247 binbuf_write(newb
, "import-result.pd", "/tmp", 0);
1252 /* function to support searching */
1253 int binbuf_match(t_binbuf
*inbuf
, t_binbuf
*searchbuf
)
1255 int indexin
, nmatched
;
1256 for (indexin
= 0; indexin
<= inbuf
->b_n
- searchbuf
->b_n
; indexin
++)
1258 for (nmatched
= 0; nmatched
< searchbuf
->b_n
; nmatched
++)
1260 t_atom
*a1
= &inbuf
->b_vec
[indexin
+ nmatched
],
1261 *a2
= &searchbuf
->b_vec
[nmatched
];
1262 if (a1
->a_type
!= a2
->a_type
||
1263 (a1
->a_type
== A_SYMBOL
&& a1
->a_w
.w_symbol
!= a2
->a_w
.w_symbol
)
1265 (a1
->a_type
== A_FLOAT
&& a1
->a_w
.w_float
!= a2
->a_w
.w_float
)
1267 (a1
->a_type
== A_DOLLAR
&& a1
->a_w
.w_index
!= a2
->a_w
.w_index
)
1269 (a1
->a_type
== A_DOLLSYM
&& a1
->a_w
.w_symbol
!= a2
->a_w
.w_symbol
))
1278 void pd_doloadbang(void);
1280 /* LATER make this evaluate the file on-the-fly. */
1281 /* LATER figure out how to log errors */
1282 void binbuf_evalfile(t_symbol
*name
, t_symbol
*dir
)
1284 t_binbuf
*b
= binbuf_new();
1285 int import
= !strcmp(name
->s_name
+ strlen(name
->s_name
) - 4, ".pat");
1286 /* set filename so that new canvases can pick them up */
1287 int dspstate
= canvas_suspend_dsp();
1288 glob_setfilename(0, name
, dir
);
1290 if (binbuf_read(b
, name
->s_name
, dir
->s_name
, 0))
1292 #if !defined(ROCKBOX) || (defined(ROCKBOX) && defined(SIMULATOR))
1293 perror(name
->s_name
);
1300 t_binbuf
*newb
= binbuf_convert(b
, 1);
1304 binbuf_eval(b
, 0, 0, 0);
1306 glob_setfilename(0, &s_
, &s_
); /* bug fix by Krzysztof Czaja */
1308 canvas_resume_dsp(dspstate
);
1311 void glob_evalfile(t_pd
*ignore
, t_symbol
*name
, t_symbol
*dir
)
1318 /* even though binbuf_evalfile appears to take care of dspstate,
1319 we have to do it again here, because canvas_startdsp() assumes
1320 that all toplevel canvases are visible. LATER check if this
1321 is still necessary -- probably not. */
1323 int dspstate
= canvas_suspend_dsp();
1324 binbuf_evalfile(name
, dir
);
1325 while ((x
!= s__X
.s_thing
) && (x
= s__X
.s_thing
))
1326 vmess(x
, gensym("pop"), "i", 1);
1328 canvas_resume_dsp(dspstate
);