#!/bin/bash

# disable globbing, for *
set -f

# list of pd internals
ilst='bang float symbol int send select route receive pack unpack trigger spigot moses until print makefilename change swap value delay metro line timer cputime realtime pipe + - * / pow & | && || << >> > >= == != <= < % mtof ftom dbtorms rmstodb dbtopow powtodb mod div sqrt log exp abs sin cos tan atan atan2 random min max notein ctlin pgmin bendin touchin polytouchin midiin sysexin noteout ctlout pgmout bendout touchout polytouchout midiout makenote stripnote tabread tabread4 tabwrite soundfiler loadbang serial netsend netreceive qlist textfile openpanel savepanel bag poly key keyup keyname declare +~ -~ *~ /~ max~ min~ clip~ q8_rsqrt~ q8_sqrt~ wrap~ fft~ ifft~ rfft~ rifft~ framp~ mtof~ ftom~ dbtorms~ rmstodb~ dbtopow~ powtodb~ dac~ adc~ sig~ line~ threshold~ snapshot~ vsnapshot~ bang~ samplerate~ send~ receive~ throw~ catch~ block~ switch~ readsf~ writesf~ phasor~ cos~ osc~ tabwrite~ tabplay~ tabread~ tabread4~ tabosc4~ tabsend~ tabreceive~ vcf~ noise~ env~ hip~ lop~ bp~ biquad~ samphold~ print~ rpole~ rzero~ rzero_rev~ cpole~ czero~ czero_rev~ delwrite~ delread~ vd~ pd table inlet outlet inlet~ outlet~ struct drawcurve drawpolygon filledpolygon filledcurve plot drawnumber pointer get set element getsize setsize append sublist list namecanvas template scope scalar array vsl hsl vradio hradio tgl cnv bng expr f r~ s~ sel t r s del'

curline=""
recursive=0
print_internals=0
recursive_opts="-r"

if [[ $1 == -r ]]; then
	recursive=1
	shift
fi

if [[ $1 == -i ]]; then
	print_internals=1
	recursive_opts="-r -i"
	shift
fi

cat $@ \
| while read line; do
	if [[ "$curline" = "" ]]; then
		curline="$line"
	else
		curline="$curline $line"
	fi
	if echo $line | grep -q -e ';$'; then
		echo $curline
		curline=""
	fi
done \
| sed -e 's/;$//' \
| awk '/^#X obj/ {print $5}' \
| sort \
| uniq \
| while read obj; do
	cont=0
	for internal in $ilst; do
		if [[ "$internal" == "$obj" ]]; then
			cont=1
			break;
		fi
	done
	if [[ $cont == 1 && $print_internals == 0 ]]; then
		continue;
	fi
	if [[ $cont == 1 ]]; then
		echo "int: $obj"
	elif [[ -f "$obj.pd" ]]; then
		echo "abs: $obj.pd"
		if [[ $recursive == 1 ]]; then
			$0 $recursive_opts "$obj.pd"
		fi
	else
		echo "obj: $obj"
	fi
done \
| sort \
| uniq
