Commit 1f016c21 authored by Miller Puckette's avatar Miller Puckette
Browse files

took various small patches

parent 27e05f64
#N canvas 376 130 488 326 12;
#X msg 67 124 bang;
#X floatatom 67 252;
#X floatatom 79 154;
#X floatatom 118 194;
#X obj 66 15 swap;
#X text 114 16 - SWAP TWO NUMBERS \, RESPECTING RIGHT-TO-LEFT ORDER;
#X text 284 309 updated for Pd version 0.27;
#X text 12 42 The swap object stores numbers from its left inlet to output on its right inlet -- after repeating its right hand input out the left.;
#X text 112 123 outputs 2 stored values;
#X obj 67 226 swap 6.5;
#X text 110 154 sets second value and outputs both;
#X text 150 195 sets first value;
#X text 142 226 creation argument initializes first value;
#X floatatom 118 254;
#X connect 0 0 9 0;
#X connect 2 0 9 0;
#X connect 3 0 9 1;
#X connect 9 0 1 0;
#X connect 9 1 13 0;
#N canvas 475 187 615 593 12;
#X msg 72 167 bang;
#X floatatom 72 292 0 0 0 0 - - -;
#X floatatom 84 200 0 0 0 0 - - -;
#X floatatom 139 237 0 0 0 0 - - -;
#X obj 33 15 swap;
#X text 81 16 - SWAP TWO NUMBERS \, RESPECTING RIGHT-TO-LEFT ORDER
;
#X text 117 166 outputs 2 stored values;
#X obj 72 266 swap 6.5;
#X text 115 200 sets second value and outputs both;
#X text 171 238 sets first value;
#X text 157 266 creation argument initializes first value;
#X floatatom 139 291 0 0 0 0 - - -;
#X obj 139 331 print right;
#X obj 72 367 print left;
#X text 43 427 A common use of swap is to reverse the operands in arithmetic
objects like this:;
#X obj 72 491 swap;
#X obj 72 519 -;
#X floatatom 72 541 5 0 0 0 - - -;
#X floatatom 103 469 3 0 0 0 - - -;
#X floatatom 72 469 3 0 0 0 - - -;
#X text 291 549 updated for Pd version 0.41;
#X text 32 52 The swap object swaps the positions of two incoming numbers.
The number coming in through the right inlet will be sent to the left
outlet and the number coming in left will come out right. Only the
left inlet is hot and triggers output on both outlets. Output order
is right to left as in [trigger].;
#X connect 0 0 7 0;
#X connect 1 0 13 0;
#X connect 2 0 7 0;
#X connect 3 0 7 1;
#X connect 7 0 1 0;
#X connect 7 1 11 0;
#X connect 11 0 12 0;
#X connect 15 0 16 0;
#X connect 15 1 16 1;
#X connect 16 0 17 0;
#X connect 18 0 15 1;
#X connect 19 0 15 0;
......@@ -14,7 +14,7 @@
#X text 39 59 The trigger object outputs its input from right to left
\, converting to the types indicated by its creation arguments. There
is also a "pointer" argument type (see the pointer object.);
#X obj 381 293 t f b l s a;
#X obj 381 293 t f b s l a;
#X msg 466 167 dog my cats;
#X obj 466 199 trigger bang anything;
#X obj 374 242 print x5;
......
......@@ -459,12 +459,12 @@ t_propertiesfn class_getpropertiesfn(t_class *c)
static t_symbol *symhash[HASHSIZE];
t_symbol *dogensym(char *s, t_symbol *oldsym)
t_symbol *dogensym(const char *s, t_symbol *oldsym)
{
t_symbol **sym1, *sym2;
unsigned int hash1 = 0, hash2 = 0;
int length = 0;
char *s2 = s;
const char *s2 = s;
while (*s2)
{
hash1 += *s2;
......@@ -491,7 +491,7 @@ t_symbol *dogensym(char *s, t_symbol *oldsym)
return (sym2);
}
t_symbol *gensym(char *s)
t_symbol *gensym(const char *s)
{
return(dogensym(s, 0));
}
......
......@@ -225,7 +225,7 @@ EXTERN t_symbol s_;
/* --------- prototypes from the central message system ----------- */
EXTERN void pd_typedmess(t_pd *x, t_symbol *s, int argc, t_atom *argv);
EXTERN void pd_forwardmess(t_pd *x, int argc, t_atom *argv);
EXTERN t_symbol *gensym(char *s);
EXTERN t_symbol *gensym(const char *s);
EXTERN t_gotfn getfn(t_pd *x, t_symbol *s);
EXTERN t_gotfn zgetfn(t_pd *x, t_symbol *s);
EXTERN void nullfn(void);
......@@ -417,6 +417,7 @@ EXTERN char *class_gethelpname(t_class *c);
EXTERN void class_setdrawcommand(t_class *c);
EXTERN int class_isdrawcommand(t_class *c);
EXTERN void class_domainsignalin(t_class *c, int onset);
EXTERN void class_set_extern_dir(t_symbol *s);
#define CLASS_MAINSIGNALIN(c, type, field) \
class_domainsignalin(c, (char *)(&((type *)0)->field) - (char *)0)
......
......@@ -250,12 +250,14 @@ static void sys_huphandler(int n)
void sys_setalarm(int microsec)
{
struct itimerval gonzo;
int sec = (int)(microsec/1000000);
microsec %= 1000000;
#if 0
fprintf(stderr, "timer %d\n", microsec);
fprintf(stderr, "timer %d:%d\n", sec, microsec);
#endif
gonzo.it_interval.tv_sec = 0;
gonzo.it_interval.tv_usec = 0;
gonzo.it_value.tv_sec = 0;
gonzo.it_value.tv_sec = sec;
gonzo.it_value.tv_usec = microsec;
if (microsec)
sys_signal(SIGALRM, sys_alarmhandler);
......
......@@ -295,7 +295,7 @@ int sys_main(int argc, char **argv)
HINSTANCE ntdll;
char filename[MAXPDSTRING];
sprintf(filename, "%s.dll", sys_externalschedlibname);
snprintf(filename, sizeof(filename), "%s.dll", sys_externalschedlibname);
sys_bashfilename(filename, filename);
ntdll = LoadLibrary(filename);
if (!ntdll)
......
This diff is collapsed.
......@@ -71,21 +71,29 @@ void sys_unbashfilename(const char *from, char *to)
/******************* Utility functions used below ******************/
/* copy until delimiter and return position after delimiter in string */
/* if it was the last substring, return NULL */
static const char* strtokcpy(char *to, const char *from, int delim)
/*!
* \brief copy until delimiter
*
* \arg to destination buffer
* \arg to_len destination buffer length
* \arg from source buffer
* \arg delim string delimiter to stop copying on
*
* \return position after delimiter in string. If it was the last
* substring, return NULL.
*/
static const char *strtokcpy(char *to, size_t to_len, const char *from, char delim)
{
int size = 0;
unsigned int i = 0;
for (; i < (to_len - 1) && from[i] && from[i] != delim; i++)
to[i] = from[i];
to[i] = '\0';
while (from[size] != (char)delim && from[size] != '\0')
size++;
if (i && from[i] != '\0')
return from + i + 1;
strncpy(to,from,size);
to[size] = '\0';
if (from[size] == '\0') return NULL;
if (size) return from+size+1;
else return NULL;
return NULL;
}
/* add a single item to a namelist. If "allowdup" is true, duplicates
......@@ -133,7 +141,7 @@ t_namelist *namelist_append_files(t_namelist *listwas, const char *s)
npos = s;
do
{
npos = strtokcpy(temp, npos, SEPARATOR);
npos = strtokcpy(temp, sizeof(temp), npos, SEPARATOR);
if (! *temp) continue;
nl = namelist_append(nl, temp, 0);
}
......
/* Copyright (c) 1999 Guenter Geiger and others.
* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
/*
* This file implements the loader for linux, which includes
* a little bit of path handling.
*
* Generalized by MSP to provide an open_via_path function
* and lists of files for all purposes.
*/
/* #define DEBUG(x) x */
#define DEBUG(x)
#include <stdlib.h>
#ifdef UNISTD
#include <unistd.h>
#include <sys/stat.h>
#endif
#ifdef MSW
#include <io.h>
#endif
#include <string.h>
#include "m_pd.h"
#include "m_imp.h"
#include "s_stuff.h"
#include <stdio.h>
#include <fcntl.h>
#include <ctype.h>
#ifdef _LARGEFILE64_SOURCE
# define open open64
# define lseek lseek64
# define fstat fstat64
# define stat stat64
#endif
t_namelist *sys_externlist;
t_namelist *sys_searchpath;
t_namelist *sys_helppath;
/* change '/' characters to the system's native file separator */
void sys_bashfilename(const char *from, char *to)
{
char c;
while (c = *from++)
{
#ifdef MSW
if (c == '/') c = '\\';
#endif
*to++ = c;
}
*to = 0;
}
/* change the system's native file separator to '/' characters */
void sys_unbashfilename(const char *from, char *to)
{
char c;
while (c = *from++)
{
#ifdef MSW
if (c == '\\') c = '/';
#endif
*to++ = c;
}
*to = 0;
}
/******************* Utility functions used below ******************/
/* copy until delimiter and return position after delimiter in string */
/* if it was the last substring, return NULL */
static const char* strtokcpy(char *to, const char *from, int delim)
{
int size = 0;
while (from[size] != (char)delim && from[size] != '\0')
size++;
strncpy(to,from,size);
to[size] = '\0';
if (from[size] == '\0') return NULL;
if (size) return from+size+1;
else return NULL;
}
/* add a single item to a namelist. If "allowdup" is true, duplicates
may be added; othewise they're dropped. */
t_namelist *namelist_append(t_namelist *listwas, const char *s, int allowdup)
{
t_namelist *nl, *nl2;
nl2 = (t_namelist *)(getbytes(sizeof(*nl)));
nl2->nl_next = 0;
nl2->nl_string = (char *)getbytes(strlen(s) + 1);
strcpy(nl2->nl_string, s);
sys_unbashfilename(nl2->nl_string, nl2->nl_string);
if (!listwas)
return (nl2);
else
{
for (nl = listwas; ;)
{
if (!allowdup && !strcmp(nl->nl_string, s))
return (listwas);
if (!nl->nl_next)
break;
nl = nl->nl_next;
}
nl->nl_next = nl2;
}
return (listwas);
}
/* add a colon-separated list of names to a namelist */
#ifdef MSW
#define SEPARATOR ';' /* in MSW the natural separator is semicolon instead */
#else
#define SEPARATOR ':'
#endif
t_namelist *namelist_append_files(t_namelist *listwas, const char *s)
{
const char *npos;
char temp[MAXPDSTRING];
t_namelist *nl = listwas, *rtn = listwas;
npos = s;
do
{
npos = strtokcpy(temp, npos, SEPARATOR);
if (! *temp) continue;
nl = namelist_append(nl, temp, 0);
}
while (npos);
return (nl);
}
void namelist_free(t_namelist *listwas)
{
t_namelist *nl, *nl2;
for (nl = listwas; nl; nl = nl2)
{
nl2 = nl->nl_next;
t_freebytes(nl->nl_string, strlen(nl->nl_string) + 1);
t_freebytes(nl, sizeof(*nl));
}
}
char *namelist_get(t_namelist *namelist, int n)
{
int i;
t_namelist *nl;
for (i = 0, nl = namelist; i < n && nl; i++, nl = nl->nl_next)
;
return (nl ? nl->nl_string : 0);
}
static t_namelist *pd_extrapath;
int sys_usestdpath = 1;
void sys_setextrapath(const char *p)
{
namelist_free(pd_extrapath);
pd_extrapath = namelist_append(0, p, 0);
}
#ifdef MSW
#define MSWOPENFLAG(bin) (bin ? _O_BINARY : _O_TEXT)
#else
#define MSWOPENFLAG(bin) 0
#endif
/* try to open a file in the directory "dir", named "name""ext",
for reading. "Name" may have slashes. The directory is copied to
"dirresult" which must be at least "size" bytes. "nameresult" is set
to point to the filename (copied elsewhere into the same buffer).
The "bin" flag requests opening for binary (which only makes a difference
on Windows). */
int sys_trytoopenone(const char *dir, const char *name, const char* ext,
char *dirresult, char **nameresult, unsigned int size, int bin)
{
int fd;
if (strlen(dir) + strlen(name) + strlen(ext) + 4 > size)
return (-1);
strcpy(dirresult, dir);
if (*dirresult && dirresult[strlen(dirresult)-1] != '/')
strcat(dirresult, "/");
strcat(dirresult, name);
strcat(dirresult, ext);
sys_bashfilename(dirresult, dirresult);
DEBUG(post("looking for %s",dirresult));
/* see if we can open the file for reading */
if ((fd=open(dirresult,O_RDONLY | MSWOPENFLAG(bin))) >= 0)
{
/* in unix, further check that it's not a directory */
#ifdef UNISTD
struct stat statbuf;
int ok = ((fstat(fd, &statbuf) >= 0) &&
!S_ISDIR(statbuf.st_mode));
if (!ok)
{
if (sys_verbose) post("tried %s; stat failed or directory",
dirresult);
close (fd);
fd = -1;
}
else
#endif
{
char *slash;
if (sys_verbose) post("tried %s and succeeded", dirresult);
sys_unbashfilename(dirresult, dirresult);
slash = strrchr(dirresult, '/');
if (slash)
{
*slash = 0;
*nameresult = slash + 1;
}
else *nameresult = dirresult;
return (fd);
}
}
else
{
if (sys_verbose) post("tried %s and failed", dirresult);
}
return (-1);
}
/* check if we were given an absolute pathname, if so try to open it
and return 1 to signal the caller to cancel any path searches */
int sys_open_absolute(const char *name, const char* ext,
char *dirresult, char **nameresult, unsigned int size, int bin, int *fdp)
{
if (name[0] == '/'
#ifdef MSW
|| (name[1] == ':' && name[2] == '/')
#endif
)
{
char dirbuf[MAXPDSTRING];
int dirlen = (strrchr(name, '/') - name);
if (dirlen > MAXPDSTRING-1)
dirlen = MAXPDSTRING-1;
strncpy(dirbuf, name, dirlen);
dirbuf[dirlen] = 0;
*fdp = sys_trytoopenone(dirbuf, name+(dirlen+1), ext,
dirresult, nameresult, size, bin);
return (1);
}
else return (0);
}
/* search for a file in a specified directory, then along the globally
defined search path, using ext as filename extension. The
fd is returned, the directory ends up in the "dirresult" which must be at
least "size" bytes. "nameresult" is set to point to the filename, which
ends up in the same buffer as dirresult. Exception:
if the 'name' starts with a slash or a letter, colon, and slash in MSW,
there is no search and instead we just try to open the file literally. */
/* see also canvas_open() which, in addition, searches down the
canvas-specific path. */
static int do_open_via_path(const char *dir, const char *name,
const char *ext, char *dirresult, char **nameresult, unsigned int size,
int bin, t_namelist *searchpath)
{
t_namelist *nl;
int fd = -1;
/* first check if "name" is absolute (and if so, try to open) */
if (sys_open_absolute(name, ext, dirresult, nameresult, size, bin, &fd))
return (fd);
/* otherwise "name" is relative; try the directory "dir" first. */
if ((fd = sys_trytoopenone(dir, name, ext,
dirresult, nameresult, size, bin)) >= 0)
return (fd);
/* next go through the search path */
for (nl = searchpath; nl; nl = nl->nl_next)
if ((fd = sys_trytoopenone(nl->nl_string, name, ext,
dirresult, nameresult, size, bin)) >= 0)
return (fd);
/* next look in "extra" */
if (sys_usestdpath &&
(fd = sys_trytoopenone(pd_extrapath->nl_string, name, ext,
dirresult, nameresult, size, bin)) >= 0)
return (fd);
*dirresult = 0;
*nameresult = dirresult;
return (-1);
}
/* open via path, using the global search path. */
int open_via_path(const char *dir, const char *name, const char *ext,
char *dirresult, char **nameresult, unsigned int size, int bin)
{
return (do_open_via_path(dir, name, ext, dirresult, nameresult,
size, bin, sys_searchpath));
}
/* Open a help file using the help search path. We expect the ".pd"
suffix here, even though we have to tear it back off for one of the
search attempts. */
void open_via_helppath(const char *name, const char *dir)
{
char realname[MAXPDSTRING], dirbuf[MAXPDSTRING], *basename;
/* make up a silly "dir" if none is supplied */
const char *usedir = (*dir ? dir : "./");
int fd;
/* 1. "objectname-help.pd" */
strncpy(realname, name, MAXPDSTRING-10);
realname[MAXPDSTRING-10] = 0;
if (strlen(realname) > 3 && !strcmp(realname+strlen(realname)-3, ".pd"))
realname[strlen(realname)-3] = 0;
strcat(realname, "-help.pd");
if ((fd = do_open_via_path(dir, realname, "", dirbuf, &basename,
MAXPDSTRING, 0, sys_helppath)) >= 0)
goto gotone;
/* 2. "help-objectname.pd" */
strcpy(realname, "help-");
strncat(realname, name, MAXPDSTRING-10);
realname[MAXPDSTRING-1] = 0;
if ((fd = do_open_via_path(dir, realname, "", dirbuf, &basename,
MAXPDSTRING, 0, sys_helppath)) >= 0)
goto gotone;
/* 3. "objectname.pd" */
if ((fd = do_open_via_path(dir, name, "", dirbuf, &basename,
MAXPDSTRING, 0, sys_helppath)) >= 0)
goto gotone;
post("sorry, couldn't find help patch for \"%s\"", name);
return;
gotone:
close (fd);
glob_evalfile(0, gensym((char*)basename), gensym(dirbuf));
}
/* Startup file reading for linux and __APPLE__. As of 0.38 this will be
deprecated in favor of the "settings" mechanism */
int sys_argparse(int argc, char **argv);
#ifndef MSW
#define STARTUPNAME ".pdrc"
#define NUMARGS 1000
int sys_rcfile(void)
{
FILE* file;
int i;
int k;
int rcargc;
char* rcargv[NUMARGS];
char* buffer;
char fname[MAXPDSTRING], buf[1000], *home = getenv("HOME");
int retval = 1; /* that's what we will return at the end; for now, let's think it'll be an error */
/* initialize rc-arg-array so we can safely clean up at the end */
for (i = 1; i < NUMARGS-1; i++)
rcargv[i]=0;
/* parse a startup file */
*fname = '\0';
strncat(fname, home? home : ".", MAXPDSTRING-10);
strcat(fname, "/");
strcat(fname, STARTUPNAME);
if (!(file = fopen(fname, "r")))
return 1;
post("reading startup file: %s", fname);
rcargv[0] = "."; /* this no longer matters to sys_argparse() */
for (i = 1; i < NUMARGS-1; i++)
{
if (fscanf(file, "%999s", buf) < 0)
break;
buf[1000] = 0;
if (!(rcargv[i] = malloc(strlen(buf) + 1)))
goto cleanup;
strcpy(rcargv[i], buf);
}
if (i >= NUMARGS-1)
fprintf(stderr, "startup file too long; extra args dropped\n");
rcargv[i] = 0;
rcargc = i;
/* parse the options */
fclose(file);
if (sys_verbose)
{
if (rcargv)
{
post("startup args from RC file:");
for (i = 1; i < rcargc; i++)
post("%s", rcargv[i]);
}
else post("no RC file arguments found");
}
if (sys_argparse(rcargc-1, rcargv+1))
{
post("error parsing RC arguments");
goto cleanup;
}
retval=0; /* we made it without an error */
cleanup: /* prevent memleak */
for (i = 1; i < NUMARGS-1; i++)
if(rcargv[i])free(rcargv[i]);
return(retval);
}
#endif /* MSW */
void sys_doflags( void)
{
int i, beginstring = 0, state = 0, len = strlen(sys_flags->s_name);
int rcargc = 0;
char *rcargv[MAXPDSTRING];
if (len > MAXPDSTRING)
{
post("flags: %s: too long", sys_flags->s_name);
return;
}
for (i = 0; i < len+1; i++)
{
int c = sys_flags->s_name[i];
if (state == 0)
{