#! /bin/sh
-# deblob-check version 2010-01-23
+# deblob-check version 2010-01-24
# Inspired in gNewSense's find-firmware script.
# Written by Alexandre Oliva <lxoliva@fsfla.org>
# recommended, because the regular expressions we use
# invoke exponential behavior in the python engine.
+# --use-perl: Choose the internal perl script. This is not
+# recommended, because our regular expressions exceed
+# some limits hard-coded into perl.
+
# --save-script-input: Save the input that would have been fed to
# any of the engines above.
rm="rm -f"
-sed=`echo $0 | sed 's,\(/\?\)[^/]*$,\1deblob-psed,'`
-if test -f "$sed"; then
- :
-elif test -f deblob-psed; then
- sed=deblob-psed
-else
- sed=false
-fi
-
-if $sed -e 'q' < /dev/null > /dev/null; then
- :
-else
- sed=sed
-fi
-
for echo in 'echo' 'printf %s\n'; do
case `$echo '\nx'` in
'\nx') break;;
# on our own, but, yuck.
if (${AWK-gawk} --re-interval --version) > /dev/null 2>&1; then
set_main_cmd=set_awk_main
+# Don't choose perl by default, we exceed some internal limits.
+elif (${PERL-perl} --version) > /dev/null 2>&1; then
+ set_main_cmd=set_perl_main
# Don't choose python by default, it exhibits exponential behavior
# (see http://swtch.com/~rsc/regexp/regexp1.html for details)
-# processing lines containing /* such as this:
-# Documentation/sysctl/*, swap/mm readaround
-# Try it: deblob-check --use-python linux-2.6.32/CREDITS
-# It hits even with our tiny testsuite:
-# AWK=false PYTHON=python deblob-check -t
-elif (${PYTHON-false} --version) > /dev/null 2>&1; then
+# processing some of our regular expressions.
+elif (${PYTHON-python} --version) > /dev/null 2>&1; then
set_main_cmd=set_python_main
# Sed takes GBs of RAM to compile all the huge regexps in the sed
# script we generate with all known false positives and blobs in Linux.
set_main_cmd=set_python_main;
;;
+--use-perl)
+ shift;
+ set_cmd=set_eqscript_cmd;
+ set_main_cmd=set_perl_main;
+ ;;
+
--use-awk)
shift;
set_cmd=set_eqscript_cmd;
case $1 in
--version | -V)
- sed -e '/^# '$name' version /,/^# Written by/ { s/^# //; p; }; d' < $0
+ ${SED-sed} -e '/^# '$name' version /,/^# Written by/ { s/^# //; p; }; d' < $0
exit 0
;;
-\? | -h)
- sed -n -e '/^# usage:/,/# -h/ { /^# -/,/^$/{s/^# \(-.*\):.*/\1/p; d; }; s/^\(# \?\)\?//p; }' < $0 &&
+ ${SED-sed} -n -e '/^# usage:/,/# -h/ { /^# -/,/^$/{s/^# \(-.*\):.*/\1/p; d; }; s/^\(# \?\)\?//p; }' < $0 &&
echo
echo "run \`$name --help | more' for full usage"
exit 0
;;
--help | -H)
- sed -n -e '/^# '$name' version /,/^[^#]/ s/^\(# \?\)\?//p' < $0
+ ${SED-sed} -n -e '/^# '$name' version /,/^[^#]/ s/^\(# \?\)\?//p' < $0
exit 0
;;
blobna 'request_ihex_firmware'
blobna 'MODULE_FIRMWARE[ ]*[(][^\n;]*[)][ ]*[;]\([ \n]*MODULE_FIRMWARE[ ]*[(][^\n;]*[)][ ]*[;]\)*'
blobna 'DEFAULT_FIRMWARE'
- blobna '\(\.\|->\)firmware[ \n]*=[^=]'
+ blobna '\([.]\|->\)firmware[ \n]*=[^=]'
blobna 'mod_firmware_load' # sound/
- blobname '\.\(fw\|bin[0-9]*\|hex\|frm\|co[dx]\|cis\|dat\|elf\|xlx\|rfb\|ucode\|img\)["]'
+ blobname '[.]\(fw\|bin[0-9]*\|hex\|frm\|co[dx]\|cis\|dat\|elf\|xlx\|rfb\|ucode\|img\)["]'
case $prefix$1 in
*/*linux*.tar* | */*kernel*.tar* | */*linux-*.*.*/*)
accept '[ ]-[ ]move[ ]firmware[ ]loading[ ]to[ ]request_firmware[(][)]' drivers/staging/slicoss/README
accept 'config[ ]FIRMWARE_IN_KERNEL.*let[ ]firmware[ ]be[ ]loaded[ ]from[ ]userspace\.' drivers/base/Kconfig
accept '[ ]*and[ ]request_firmware[(][)][ ]in[ ]the[ ]source' drivers/base/Kconfig
- accept 'static[ ]int[\n]_request_firmware[(]const[ ]struct[ ]firmware[ ][*][*]firmware_p,[ ]const[ ]char[ ][*]name,[^{]*[\n][{][\n]\([^}]\|[^\n}][}]*\)*[\n][}][\n]' drivers/base/firmware_class.c
- accept 'static[ ]int[\n]request_firmware_work_func[(]void[ ][*]arg[)][\n][{][\n]\([^}]\|[^\n}][}]*\)*ret[ ]=[ ]_request_firmware[(]\([^}]\|[^\n}][}]*\)*[\n][}][\n]' drivers/base/firmware_class.c
- accept '[/][*][*][\n][ ][*][ ]request_firmware:[ ]-[ ]send[ ]firmware[ ][^{]*[\n][{][\n]\([^}]\|[^\n}][}]*\)*[\n][}][\n]' drivers/base/firmware_class.c
- accept '[/][*][*][\n][ ][*][ ]request_firmware_nowait:[ ]asynchronous[ ]version[^{]*[\n][{][\n]\([^}]\|[^\n}][}]*\)*[\n][}][\n]' drivers/base/firmware_class.c
+ accept 'static[ ]int[\n]_request_firmware[(]const[ ]struct[ ]firmware[ ][*][*]firmware_p,[ ]const[ ]char[ ][*]name,[^{]*[\n][{][\n]\([\n]*[^\n}][}]*\)*[\n]\+[}][\n]' drivers/base/firmware_class.c
+ accept 'static[ ]int[\n]request_firmware_work_func[(]void[ ][*]arg[)][\n][{][\n]\([\n]*[^\n}][}]*\)*ret[ ]=[ ]_request_firmware[(]\([\n]*[^\n}][}]*\)*[\n]\+[}][\n]' drivers/base/firmware_class.c
+ accept '[/][*][*][\n][ ][*][ ]request_firmware:[ ]-[ ]send[ ]firmware[ ][^{]*[\n][{][\n]\([\n]*[^\n}][}]*\)*[\n]\+[}][\n]' drivers/base/firmware_class.c
+ accept '[/][*][*][\n][ ][*][ ]request_firmware_nowait:[ ]asynchronous[ ]version[^{]*[\n][{][\n]\([\n]*[^\n}][}]*\)*[\n]\+[}][\n]' drivers/base/firmware_class.c
accept 'EXPORT_SYMBOL[(]request_firmware\(_nowait\)\?[)][;]' drivers/base/firmware_class.c
accept 'int[ ]request_firmware\(_nowait\)\?[(][^;]*[)][;]' include/linux/firmware.h
accept 'static[ ]inline[ ]int[ ]request_firmware\(_nowait\)\?[(][^{]*[)][\n][{][\n][ ]return[ ]-EINVAL[;][\n][}]' include/linux/firmware.h
- accept 'static[ ]inline[ ]int[\n]\(maybe_\)\?reject_firmware\(_nowait\)\?[(][^{;]*[)][\n][{][\n]\([^}]\|[^\n}][}]*\)*[\n][}]' include/linux/firmware.h
+ accept 'static[ ]inline[ ]int[\n]\(maybe_\)\?reject_firmware\(_nowait\)\?[(][^{;]*[)][\n][{][\n]\([\n]*[^\n}][}]*\)*[\n]\+[}]' include/linux/firmware.h
- accept 'static[ ]inline[ ]int[ ]request_ihex_firmware\?[(][^{]*[)][\n][{][\n]\([^}]\|[^\n}][}]*\)*[\n][}][\n]' include/linux/ihex.h
+ accept 'static[ ]inline[ ]int[ ]request_ihex_firmware\?[(][^{]*[)][\n][{][\n]\([\n]*[^\n}][}]*\)*[\n]\+[}][\n]' include/linux/ihex.h
ocomment '[/][*][ ]Optional[ ]firmware\([^\n]*[\n][ ][*]\)*[^\n]*[ ]MODULE_FIRMWARE[(][)]'
oprepline '#define[ ]MODULE_FIRMWARE[(]_firmware[)]' include/linux/module.h
accept '[ ][*][ ]Sample[ ]code[ ]on[ ]how[ ]to[ ]use[ ]request_firmware[(][)][ ]from[ ]drivers\.' samples/firmware_class/firmware_sample_driver.c
blob '\(#\(ifdef[ ]AMB_NEW_MICROCODE\|else\|endif\)[\n]#\(define\|include\)[ ]UCODE2\?[(][^\n]*[\n]\)\+\([\n]*static[ ]\(u32\|region\)[ ]__devinitdata[ ]ucode_\(start\|\(regions\|data\)\[\]\)[ ]=[^;]*[;]\)*' drivers/atm/ambassador.c
blobname '\(pca\|sba\)200e\(_ecd\)\?\.\(data\|bin[12]\?\)' 'drivers/atm/\(Makefile\|fore200e\(_mkfirm\)\?\.c\)'
- blobna '[/][*][/]*\([*]*[^*/][^*/]*[/]*\)*[*]*PCA-200E[ ]firmware[ ][*][/]' drivers/atm/fore200e_mkfirm.c
+ blobna '[/][*][/]*\([*]*[^*/][/]*\)*[*]*PCA-200E[ ]firmware[ ][*][/]' drivers/atm/fore200e_mkfirm.c
blobna '_fore200e_\(pca\|sba\)_fw_\(data\|size\)' drivers/atm/fore200e.c
blob '#ifdef[ ]CONFIG_ATM_FORE200E_\(PCA\|SBA\)\([\n]extern[ ]const[ ]unsigned[ ]\(char\|int\)[ ]*_fore200e_\(pca\|sba\)_fw_\(data\[\]\|size\)[;]\)\+[\n]#endif\([\n]\+#ifdef[ ]CONFIG_ATM_FORE200E_\(PCA\|SBA\)\([\n]extern[ ]const[ ]unsigned[ ]\(char\|int\)[ ]*_fore200e_\(pca\|sba\)_fw_\(data\[\]\|size\)[;]\)\+[\n]#endif\)*' drivers/atm/fore200e.c
blobname 'intelliport2\.bin' drivers/char/ip2/ip2main.c
blob 'static[ ]unsigned[ ]char[ ]warp_g[24]00_t2\?gzs\?a\?f\?\[\][ ]=[ ][{][^{};]*[}][;]\([\n][\n]*static[ ]unsigned[ ]char[ ]warp_g[24]00_t2\?gzs\?a\?f\?\[\][ ]=[ ][{][^{};]*[}][;]\)*' drivers/gpu/drm/mga/mga_ucode.h
- blob '\(#define[ ]WARP_UCODE_\(SIZE\|INSTALL\)[(][ ]*which\([^\n]*\\[ ]*[\n]\)*[^\n]*\|static[ ]const[ ]unsigned[ ]int[ ]mga_warp_g[24]00_microcode_size[ ]=[^;]*[;]\|static[ ]int[ ]mga_warp_install_g[24]00_microcode[(][^{]*[)][\n][{][\n]\([^}]\|[^\n}][}]*\)*[\n][}]\)\([\n][\n]*\(#define[ ]WARP_UCODE_\(SIZE\|INSTALL\)[(][ ]*which\([^\n]*\\[ ]*[\n]\)*[^\n]*\|static[ ]const[ ]unsigned[ ]int[ ]mga_warp_g[24]00_microcode_size[ ]=[^;]*[;]\|static[ ]int[ ]mga_warp_install_g[24]00_microcode[(][^{]*[)][\n][{][\n]\([^}]\|[^\n}][}]*\)*[\n][}]\)\)*' drivers/gpu/drm/mga/mga_warp.c
+ blob '\(#define[ ]WARP_UCODE_\(SIZE\|INSTALL\)[(][ ]*which\([^\n]*\\[ ]*[\n]\)*[^\n]*\|static[ ]const[ ]unsigned[ ]int[ ]mga_warp_g[24]00_microcode_size[ ]=[^;]*[;]\|static[ ]int[ ]mga_warp_install_g[24]00_microcode[(][^{]*[)][\n][{][\n]\([\n]*[^\n}][}]*\)*[\n]\+[}]\)\([\n][\n]*\(#define[ ]WARP_UCODE_\(SIZE\|INSTALL\)[(][ ]*which\([^\n]*\\[ ]*[\n]\)*[^\n]*\|static[ ]const[ ]unsigned[ ]int[ ]mga_warp_g[24]00_microcode_size[ ]=[^;]*[;]\|static[ ]int[ ]mga_warp_install_g[24]00_microcode[(][^{]*[)][\n][{][\n]\([\n]*[^\n}][}]*\)*[\n]\+[}]\)\)*' drivers/gpu/drm/mga/mga_warp.c
blobna '\(case[ ]MGA_CARD_TYPE_G[^:]*:[ \n]*\)\+return[ ][^;]*mga_warp[^;]*microcode[^;]*[;]\([ \n]*\(case[ ]MGA_CARD_TYPE_G[^:]*:[ \n]*\)\+return[ ][^;]*mga_warp[^;]*microcode[^;]*[;][ ]*\)*' drivers/gpu/drm/mga/mga_warp.c
blob 'static[ ]u32[ ]r128_cce_microcode\[\][ ]=[ ][{][^;]*[}][;]' drivers/gpu/drm/r128/r128_cce.c
- blob 'static[ ]void[ ]r128_cce_load_microcode[(][^{]*[)][\n][{][\n]\([^}]\|[^\n}][}]*\)*[\n][}]' drivers/gpu/drm/r128/r128_cce.c
+ blob 'static[ ]void[ ]r128_cce_load_microcode[(][^{]*[)][\n][{][\n]\([\n]*[^\n}][}]*\)*[\n]\+[}]' drivers/gpu/drm/r128/r128_cce.c
# blobna 'R128_WRITE[(]R128_PM4_MICROCODE_DATA[HL],[\n ]*r128_cce_microcode\[i[ ][*][ ]2\([ ][+][ ]1\)\?\][)]\([;][\n ]*R128_WRITE[(]R128_PM4_MICROCODE_DATA[HL],[\n ]*r128_cce_microcode\[i[ ][*][ ]2\([ ][+][ ]1\)\?\][)]\)*' drivers/gpu/drm/r128/r128_cce.c
blob 'static[ ]const[ ]u32[ ]R[SV0-9]*[05]_\(c\|pf\)p_microcode\[\]\(\[[23]\]\)\?[ ]=[ ][{][^;]*[}][;]\([\n][\n]*static[ ]const[ ]u32[ ]R[SV0-9]*[05]_\(c\|pf\)p_microcode\[\]\(\[[23]\]\)\?[ ]=[ ][{][^;]*[}][;]\)*' 'drivers/gpu/drm/radeon/\(radeon\|r600\)_microcode\.h'
- blob 'static[ ]void[ ]r\(adeon\|[167]00\)_cp_load_microcode[(][^{]*[)][\n][{][\n]\([^}]\|[^\n}][}]*\)*cp_microcode\([^}]\|[^\n}][}]*\)*[\n][}]' 'drivers/gpu/drm/radeon/r\(\(adeon\|600\)_cp\|100\)\.c'
+ blob 'static[ ]void[ ]r\(adeon\|[167]00\)_cp_load_microcode[(][^{]*[)][\n][{][\n]\([\n]*[^\n}][}]*\)*cp_microcode\([\n]*[^\n}][}]*\)*[\n]\+[}]' 'drivers/gpu/drm/radeon/r\(\(adeon\|600\)_cp\|100\)\.c'
# blobna 'RADEON_WRITE[(]R\(ADEON\|600\)_CP_\(ME_RAM\|PFP_UCODE\)_DATA[HL]\?,[\n ]*R[SV0-9]*[05]_\(c\|pf\)p_microcode\[i\]\(\[[012]\]\)\?[)]\([;][\n ]*RADEON_WRITE[(]R\(ADEON\|600\)_CP_\(ME_RAM\|PFP_UCODE\)_DATA[HL]\?,[\n ]*R[SV0-9]*[05]_\(c\|pf\)p_microcode\[i\]\(\[[012]\]\)\?[)]\)*' 'drivers/gpu/drm/radeon/\(radeon\|r600\)_cp\.c'
blob 'sub[ ]\(sp887[0x]\|tda1004\(5\|6\(lifeview\)\?\)\|av7110\|dec\(2\(00\|54\)0t\|3000s\)\|opera1\|vp7041\|dibusb\|nxt200[24]cx\(23\(1xx\|855\)\|18\)\|pvrusb2\|or51\(211\|132_\(qam\|vsb\)\)\|bluebird\|mpc718\)[ ]*[{]\([^}]*\|[^\n}][}]*\)[\n][}]\([\n][\n]*sub[ ]\(sp887[0x]\|tda1004\(5\|6\(lifeview\)\?\)\|av7110\|dec\(2\(00\|54\)0t\|3000s\)\|opera1\|vp7041\|dibusb\|nxt200[24]cx\(23\(1xx\|855\)\|18\)\|pvrusb2\|or51\(211\|132_\(qam\|vsb\)\)\|bluebird\|mpc718\)[ ]*[{]\([^}]*\|[^\n}][}]*\)[\n][}]\)*' Documentation/dvb/get_dvb_firmware
blobna '[\n][ ]scriptlen[ ]=[ ]sizeof[(]script[)][^;]*[;][\n][ ]for[^{]*scriptlen[^{]*[{][^}]*[^\n }]' drivers/media/dvb/dvb-usb/af9005-fe.c
accept 'struct[ ]\(sp8870\|tda1004x\)_config[\n][{][^}]*[(][*]request_firmware[)][^}]*[\n][}][;]' 'drivers/media/dvb/frontends/\(sp8870\|tda1004x\)\.h'
- blob '[/][*][/]*\([*]*[^*/][^*/]*[/]*\)*[*]*get_dvb_firmware[/]*\([*]*[^*/][^*/]*[/]*\)*[*]*[*][/]\([\n]\(#define[ ]\(\([^\n ]*_DEFAULT\|NONFREE\)_FIRMWARE\|["][^"]*["]\)[ ]\([^\n]\|[\\][\n]\)*\|[/][*][(]DEBLOBBED[)][*][/]\)\)*' 'drivers/media/dvb/frontends/\(nxt200x\|or51211\|sp887[0x]\|tda1004[8x]\)\.c'
+ blob '[/][*][/]*\([*]*[^*/][/]*\)*[*]*get_dvb_firmware[/]*\([*]*[^*/][/]*\)*[*]*[*][/]\([\n]\(#define[ ]\(\([^\n ]*_DEFAULT\|NONFREE\)_FIRMWARE\|["][^"]*["]\)[ ]\([^\n]\|[\\][\n]\)*\|[/][*][(]DEBLOBBED[)][*][/]\)\)*' 'drivers/media/dvb/frontends/\(nxt200x\|or51211\|sp887[0x]\|tda1004[8x]\)\.c'
blobname 'dvb-fe-sp8870\.fw' drivers/media/dvb/frontends/sp8870.c
blobname 'dvb-fe-tda1004[56]\.fw' drivers/media/dvb/frontends/tda1004x.c
blob 'static[ ]u32[ ]tigon2\?Fw\(Text\|Rodata\|Data\)\[[(]MAX_\(TEXT\|RODATA\|DATA\)_LEN[/]4[)][ ][+][ ]1\][ ]__devinitdata[ ]=[ ][{][^}]*[}][;]\([\n]static[ ]u32[ ]tigon2\?Fw\(Text\|Rodata\|Data\)\[[(]MAX_\(TEXT\|RODATA\|DATA\)_LEN[/]4[)][ ][+][ ]1\][ ]__devinitdata[ ]=[ ][{][^}]*[}][;]\)*' drivers/net/acenic_firwmare.h
blob '#define[ ]tigon2\?Fw[^ ]*\(Addr\|Len\)[ ]0x[^\n]*\([\n]#define[ ]tigon2\?Fw[^ ]*\(Addr\|Len\)[ ]0x[^\n]*\)\+' drivers/net/acenic_firmware.h
- blob '\([/][*][/]*\([*]*[^*/][^*/]*[/]*\)*[*]*Do[ ]not[ ]try[ ]to[ ]clear[/]*\([*]*[^*/][^*/]*[/]*\)*[*]*[*][/][\n][ ]\)\?ace_clear[^;]*[;][\n]\([^}]*[{][^}]*ace_copy[^}]*tigon2\?Fw[^}]*[}]\)*[\n]\+[ ]return[ ]0[;][\n][}]' drivers/net/acenic.c
+ blob '\([/][*][/]*\([*]*[^*/][/]*\)*[*]*Do[ ]not[ ]try[ ]to[ ]clear[/]*\([*]*[^*/][/]*\)*[*]*[*][/][\n][ ]\)\?ace_clear[^;]*[;][\n]\([^}]*[{][^}]*ace_copy[^}]*tigon2\?Fw[^}]*[}]\)*[\n]\+[ ]return[ ]0[;][\n][}]' drivers/net/acenic.c
blob 'if[ ][(]\(ACE_IS_TIGON_I[(]ap[)]\|ap->version[ ]==[ ]2\)[)][\n][ ][ ]writel[(]tigon2\?FwStartAddr,[ ][&]regs->Pc[)][;]\([\n][ ]if[ ][(]\(ACE_IS_TIGON_I[(]ap[)]\|ap->version[ ]==[ ]2\)[)][\n][ ][ ]writel[(]tigon2\?FwStartAddr,[ ][&]regs->Pc[)][;]\)*' drivers/net/acenic.c
blob '#include[ ]["]starfire_firmware\.h["]' drivers/net/starfire.c
- blob '[/][*][/]*\([*]*[^*/][^*/]*[/]*\)*[*]*Load[ ]Rx[/]Tx[ ]firmware[/]*\([*]*[^*/][^*/]*[/]*\)*[*]*[*][/]\([\n][ ]for[ ][(][^)]*FIRMWARE_[RT]X_SIZE[^)]*[)][\n][ ][ ]writel[^;]*firmware_[rt]x[^;]*[;]\)\+' drivers/net/starfire.c
+ blob '[/][*][/]*\([*]*[^*/][/]*\)*[*]*Load[ ]Rx[/]Tx[ ]firmware[/]*\([*]*[^*/][/]*\)*[*]*[*][/]\([\n][ ]for[ ][(][^)]*FIRMWARE_[RT]X_SIZE[^)]*[)][\n][ ][ ]writel[^;]*firmware_[rt]x[^;]*[;]\)\+' drivers/net/starfire.c
blob 'static[ ]\(u8\|const[ ]u32\|struct[ ]fw_info\)[ ]bnx2_\(\(COM\|CP\|[RT]XP\|TPAT\)_b0[69]Fw\(Text\|Data\|Rodata\)\|\(xi_\)\?rv2p_proc[12]\|\(com\|cp\|[rt]xp\|tpat\)_fw_0[69]\)\(\[[^]};]*\]\)*[ ]=[ ][{][^}]*[}][;]\([\n][\n]*static[ ]\(u8\|const[ ]u32\|struct[ ]fw_info\)[ ]bnx2_\(\(COM\|CP\|[RT]XP\|TPAT\)_b0[69]Fw\(Text\|Data\|Rodata\)\|\(xi_\)\?rv2p_proc[12]\|\(com\|cp\|[rt]xp\|tpat\)_fw_0[69]\)\(\[[^]};]*\]\)*[ ]=[ ][{][^}]*[}][;]\)*' 'drivers/net/bnx2_fw2\?.h'
blob '#include[ ]["]bnx2_fw\.h["][\n][\n]*#include[ ]["]bnx2_fw2\.h["]' drivers/net/bnx2.c
- blob 'static[ ]void[\n]load_rv2p_fw[(][^{]*[)][\n][{][\n]\([^}]\|[^\n}][}]*\)*[\n][}]' drivers/net/bnx2.c
- blob 'static[ ]int[\n]bnx2_init_cpus[(][^{]*[)][\n][{][\n]\([^}]\|[^\n}][}]*\)*[\n][}]' drivers/net/bnx2.c
+ blob 'static[ ]void[\n]load_rv2p_fw[(][^{]*[)][\n][{][\n]\([\n]*[^\n}][}]*\)*[\n]\+[}]' drivers/net/bnx2.c
+ blob 'static[ ]int[\n]bnx2_init_cpus[(][^{]*[)][\n][{][\n]\([\n]*[^\n}][}]*\)*[\n]\+[}]' drivers/net/bnx2.c
# init_data_e1h? might actually be just data, but it doesn't
# really matter.
blob 'static[ ]const[ ]u32[ ]\(init\?\|[tucx]sem_\(int_table\|pram\)\)_data_e1h\?\[\][ ]=[ ][{][^}]*[}][;]\([\n][\n]*static[ ]const[ ]u32[ ]\(init\?\|[tucx]sem_\(int_table\|pram\)\)_data_e1h\?\[\][ ]=[ ][{][^}]*[}][;]\)*' drivers/net/bnx2x_init_values.h
- blob 'static[ ]\(void[ ]\|const[ ]u32[ ][*]\)bnx2x_\(sel_blob\|init_wr_wb\|init_block\)[(][^{]*[)][\n][{][\n]\([^}]\|[^\n}][}]*\)*[\n][}]\([\n][\n]*static[ ]\(void[ ]\|const[ ]u32[ ][*]\)bnx2x_\(sel_blob\|init_wr_wb\|init_block\)[(][^{]*[)][\n][{][\n]\([^}]\|[^\n}][}]*\)*[\n][}]\)*' 'drivers/net/bnx2x_init\(_ops\)\?\.h'
+ blob 'static[ ]\(void[ ]\|const[ ]u32[ ][*]\)bnx2x_\(sel_blob\|init_wr_wb\|init_block\)[(][^{]*[)][\n][{][\n]\([\n]*[^\n}][}]*\)*[\n]\+[}]\([\n][\n]*static[ ]\(void[ ]\|const[ ]u32[ ][*]\)bnx2x_\(sel_blob\|init_wr_wb\|init_block\)[(][^{]*[)][\n][{][\n]\([\n]*[^\n}][}]*\)*[\n]\+[}]\)*' 'drivers/net/bnx2x_init\(_ops\)\?\.h'
blobname 'sun[/]cassini\.bin' drivers/net/cassini.c
blobna 'for[ ][(][^\n]*ARRAY_SIZE[(]\(sr\|twinax\)_edc[)][^\n]*[)][\n][^;]*mdio_write[^;]*[;]' drivers/net/cxgb3/ael1002.c
blobname '\(cxgb3[/]\)\?t3\(fw\|\(%c\|.\)_p\(rotocol_\)\?sram\)-\(%d\|[0-9]*\)\.\(%d\|[0-9]*\)\.\(%d\|[0-9]*\)\.bin' drivers/net/cxgb3/cxgb3_main.c
- blob '\([/][*][*]*[*][/][\n]*\)*\([/][*][/]*\([*]*[^*/][^*/]*[/]*\)*[*]*Micro[ ]code[/]*\([*]*[^*/][^*/]*[/]*\)*[*]*8086:[/]*\([*]*[^*/][^*/]*[/]*\)*[*]*[*][/]\([\n]*[/][*][/]*\([*]*[^*/][^*/]*[/]*\)*[*]*[*][/]\)*\|#define[ ][ ]*D10\(1M\(_B\)\?\|1S\|2_E\)_\(CPUSAVER_\(TIMER\|BUNDLE\|MIN_SIZE\)_DWORD\|RCVBUNDLE_UCODE\)[ ]\(\\[\n]\|[^\n]\)*\)\([\n]*[/][*][/]*\([*]*[^*/][^*/]*[/]*\|[*]*[*][/][\n]*[/][*]\)*[*]*Micro[ ]code[/]*\([*]*[^*/][^*/]*[/]*\)*[*]*8086:[/]*\([*]*[^*/][^*/]*[/]*\)*[*]*[*][/]\([\n]*[/][*][/]*\([*]*[^*/][^*/]*[/]*\)*[*]*[*][/]\)*\|[\n][\n]*#define[ ][ ]*D10\(1M\(_B\)\?\|1S\|2_E\)_\(CPUSAVER_\(TIMER\|BUNDLE\|MIN_SIZE\)_DWORD\|RCVBUNDLE_UCODE\)[ ]\(\\[\n]\|[^\n]\)*\)*' drivers/net/e100.c
- blobna '\([/][*][/]*\([*]*[^*/][^*/]*[/]*\)*[*]*[*][/][\n]*[ ][ ]\)\(ucode\[opts->\(timer\|bundle\|min_size\)_dword\][ ].=[ ][^;]*[;][\n][\n]*[ ][ ]\)*[^}]*UCODE_SIZE[^}]*cb_ucode[^}]*return[;][\n][ ][}]' drivers/net/e100.c
+ blob '\([/][*][*]*[*][/][\n]*\)*\([/][*][/]*\([*]*[^*/][/]*\)*[*]*Micro[ ]code[/]*\([*]*[^*/][/]*\)*[*]*8086:[/]*\([*]*[^*/][/]*\)*[*]*[*][/]\([\n]*[/][*][/]*\([*]*[^*/][/]*\)*[*]*[*][/]\)*\|#define[ ][ ]*D10\(1M\(_B\)\?\|1S\|2_E\)_\(CPUSAVER_\(TIMER\|BUNDLE\|MIN_SIZE\)_DWORD\|RCVBUNDLE_UCODE\)[ ]\(\\[\n]\|[^\n]\)*\)\([\n]*[/][*][/]*\([*]*[^*/][^*/]*[/]*\|[*]*[*][/][\n]*[/][*]\)*[*]*Micro[ ]code[/]*\([*]*[^*/][/]*\)*[*]*8086:[/]*\([*]*[^*/][/]*\)*[*]*[*][/]\([\n]*[/][*][/]*\([*]*[^*/][/]*\)*[*]*[*][/]\)*\|[\n][\n]*#define[ ][ ]*D10\(1M\(_B\)\?\|1S\|2_E\)_\(CPUSAVER_\(TIMER\|BUNDLE\|MIN_SIZE\)_DWORD\|RCVBUNDLE_UCODE\)[ ]\(\\[\n]\|[^\n]\)*\)*' drivers/net/e100.c
+ blobna '\([/][*][/]*\([*]*[^*/][/]*\)*[*]*[*][/][\n]*[ ][ ]\)\(ucode\[opts->\(timer\|bundle\|min_size\)_dword\][ ].=[ ][^;]*[;][\n][\n]*[ ][ ]\)*[^}]*UCODE_SIZE[^}]*cb_ucode[^}]*return[;][\n][ ][}]' drivers/net/e100.c
blob 'static[ ]unsigned[ ]char[ ]__devinitdata[ ]lanai4_\(code\|data\)\[[0-9]*\][ ]=[ ][{][^;]*[}][;]' drivers/net/myri_code.h
blob '#include[ ]["]myri_code\.h["]' drivers/net/myri_sbus.c
- blobna '\([/][*][/]*\([*]*[^*/][^*/]*[/]*\)*[*]*[*][/][\n ]*\)\?for[ ][(][^\n]*sizeof[(]lanai4_\(code\|data\)[^\n]*[)][\n][^\n]*sbus_writeb[^;]*lanai4_\(code\|data\)[^;]*lanai4_code_off[^;]*[;]\([\n ]*\([/][*][/]*\([*]*[^*/][^*/]*[/]*\)*[*]*[*][/][\n ]*\)\?for[ ][(][^\n]*sizeof[(]lanai4_\(code\|data\)[^\n]*[)][\n][^\n]*sbus_writeb[^;]*lanai4_\(code\|data\)[^;]*lanai4_\(code\|data\)_off[^;]*[;]\)*' drivers/net/myri_sbus.c
+ blobna '\([/][*][/]*\([*]*[^*/][/]*\)*[*]*[*][/][\n ]*\)\?for[ ][(][^\n]*sizeof[(]lanai4_\(code\|data\)[^\n]*[)][\n][^\n]*sbus_writeb[^;]*lanai4_\(code\|data\)[^;]*lanai4_code_off[^;]*[;]\([\n ]*\([/][*][/]*\([*]*[^*/][/]*\)*[*]*[*][/][\n ]*\)\?for[ ][(][^\n]*sizeof[(]lanai4_\(code\|data\)[^\n]*[)][\n][^\n]*sbus_writeb[^;]*lanai4_\(code\|data\)[^;]*lanai4_\(code\|data\)_off[^;]*[;]\)*' drivers/net/myri_sbus.c
blob 'static[ ]u32[ ]s_firmLoad\[\][ ]=[ ][{][^;]*[}][;]' drivers/net/tehuti_fw.h
blob 'bdx_tx_push_desc_safe[^;]*s_firmLoad[^;]*[;]' drivers/net/tehuti.c
blob '[ ][*][ ]Firmware[ ]is:[\n][ ][*][ ]Derived[ ]from[ ]proprietary[^/]*notice[ ]is[ ]accompanying[ ]it\.[\n][ ][*][/]' drivers/net/tg3.c
blob 'Derived[ ]from[ ]proprietary[ ]unpublished[ ]source[ ]code' drivers/net/tg3.c
- blob '\(static[ ]const[ ]\)\?u32[ ]tg3\(Tso5\?\)\?Fw\(Text\|Rodata\|Data\)\[[^{]*\][ ]=[ ][{][^}]*[}][;]\([\n][\n]*\(static[ ]const[ ]u32[ ]tg3\(Tso5\?\)\?Fw\(Text\|Rodata\|Data\)\[[^{]*\][ ]=[ ][{][^}]*[}][;]\|#if[ ]0\([ ][/][*][/]*\([*]*[^*/][^*/]*[/]*\)*[*]*[*][/]\)\?[\n]\(static[ ]const[ ]\)\?u32[ ]tg3\(Tso5\?\)\?Fw\(Text\|Rodata\|Data\)\[[^{]*\][ ]=[ ][{][^}]*[}][;][\n]#endif\)\)*' drivers/net/tg3.c
+ blob '\(static[ ]const[ ]\)\?u32[ ]tg3\(Tso5\?\)\?Fw\(Text\|Rodata\|Data\)\[[^{]*\][ ]=[ ][{][^}]*[}][;]\([\n][\n]*\(static[ ]const[ ]u32[ ]tg3\(Tso5\?\)\?Fw\(Text\|Rodata\|Data\)\[[^{]*\][ ]=[ ][{][^}]*[}][;]\|#if[ ]0\([ ][/][*][/]*\([*]*[^*/][/]*\)*[*]*[*][/]\)\?[\n]\(static[ ]const[ ]\)\?u32[ ]tg3\(Tso5\?\)\?Fw\(Text\|Rodata\|Data\)\[[^{]*\][ ]=[ ][{][^}]*[}][;][\n]#endif\)\)*' drivers/net/tg3.c
blob 'static[ ]const[ ]u8[ ]typhoon_firmware_image\[\][ ]=[ ][{][^}]*[}][;]' drivers/net/typhoon-firmware.h
blobna 'licensed[^\n]*strictly[ ]for[ ]use[^\n]*[\n]*[^\n]*COPS[ ]LocalTalk' 'drivers/net/appletalk/cops_\(ff\|lt\)drv\.h'
blob 'static[ ]const[ ]unsigned[ ]char[ ]ffdrv_code\[\][ ]=[ ][{][^}]*[}][;]' drivers/net/appletalk/cops_ffdrv.h
blob 'static[ ]const[ ]unsgined[ ]char[ ]ltdrv_code\[\][ ]=[ ][{][^}]*[}][;]' drivers/net/appletalk/cops_ltdrv.h
- blob '#include[ ]["]cops_\(lt\|ff\)drv\.h["][ ]*\([/][*][/]*\([*]*[^*/][^*/]*[/]*\)*[*]*Firmware[/]*\([*]*[^*/][^*/]*[/]*\)*[*]*[*][/]\)\?\([\n][\n]*#include[ ]["]cops_\(lt\|ff\)drv\.h["][ ]*\([/][*][/]*\([*]*[^*/][^*/]*[/]*\)*[*]*Firmware[/]*\([*]*[^*/][^*/]*[/]*\)*[*]*[*][/]\)\?\)*' drivers/net/appletalk/cops.c
+ blob '#include[ ]["]cops_\(lt\|ff\)drv\.h["][ ]*\([/][*][/]*\([*]*[^*/][/]*\)*[*]*Firmware[/]*\([*]*[^*/][/]*\)*[*]*[*][/]\)\?\([\n][\n]*#include[ ]["]cops_\(lt\|ff\)drv\.h["][ ]*\([/][*][/]*\([*]*[^*/][/]*\)*[*]*Firmware[/]*\([*]*[^*/][/]*\)*[*]*[*][/]\)\?\)*' drivers/net/appletalk/cops.c
blob 'static[ ]unsigned[ ]char[ ]bits_1200\[\][ ]*=[ ][{][^}]*[}][;]' drivers/net/hamradio/yam1200.h
blob 'static[ ]unsigned[ ]char[ ]bits_9600\[\][ ]*=[ ][{][^}]*[}][;]' drivers/net/hamradio/yam9600.h
blob 'static[ ]const[ ]u8[ ]microcode\[\][ ]=[ ][{][^}]*[}][ ]*[;]' drivers/net/tokenring/3c359_microcode.h
blob '#include[ ]["]3c359_microcode\.h["]' drivers/net/tokenring/3c359.c
- blobna 'start[ ]=[ ][(]0xFFFF[ ]-[ ][(]mc_size[)][^;]*[;][\n ]*[/][*][/]*\([*]*[^*/][^*/]*[/]*\)*[*]*[*][/][\n ]*printk[(]KERN_INFO[ ]["]3C359:[ ]Uploading[ ]Microcode:[ ]["][)][;][\n ]*for[ ][(][^{]*\(mc_size[^{]*[)][ ][{][^}]*writeb[(]microcode\[\|[)][ ][{][^}]*writeb[(]microcode\[mc_size\)[^}]*[}]\([\n][ ]*printk[^\n]*[;][\n ]*for[ ][(][^{]*\(mc_size[^{]*[)][ ][{][^}]*writeb[(]microcode\[\|[)][ ][{][^}]*writeb[(]microcode\[mc_size\)[^}]*[}]\)*' drivers/net/tokenring/3c359.c
+ blobna 'start[ ]=[ ][(]0xFFFF[ ]-[ ][(]mc_size[)][^;]*[;][\n ]*[/][*][/]*\([*]*[^*/][/]*\)*[*]*[*][/][\n ]*printk[(]KERN_INFO[ ]["]3C359:[ ]Uploading[ ]Microcode:[ ]["][)][;][\n ]*for[ ][(][^{]*\(mc_size[^{]*[)][ ][{][^}]*writeb[(]microcode\[\|[)][ ][{][^}]*writeb[(]microcode\[mc_size\)[^}]*[}]\([\n][ ]*printk[^\n]*[;][\n ]*for[ ][(][^{]*\(mc_size[^{]*[)][ ][{][^}]*writeb[(]microcode\[\|[)][ ][{][^}]*writeb[(]microcode\[mc_size\)[^}]*[}]\)*' drivers/net/tokenring/3c359.c
blobname 'tr_smctr\.bin' drivers/net/tokenring/smctr.c
blob 'unsigned[ ]short[ ]sbus_risc_code01\[\][ ]__devinitdata[ ]=[ ][{][^}]*[}][;]' drivers/scsi/qlogicpti_asm.c
blob '#include[ ]["]qlogicpti_asm\.c["]' drivers/scsi/qlogicpti.c
- blob '\([/][*][ ]Microcode[/]*\([*]*[^*/][^*/]*[/]*\)*[*]*[*][/][\n]*\)\?static[ ]\(u\(nsigned[ ]\)\?char\|unsigned[ ]short\|ADV_DCNT\)[ ]_\(asc_mcode\|adv_asc3\(550\|8C\(08\|16\)00\)\)_\(buf\[\][ ]=[ ][{][^}]*[}]\|size[ ]=[ ]sizeof[^;]*\|chksum[ ]=[ ]0x[^;]*\)[;]\([ ]*[/][*][/]*\([*]*[^*/][^*/]*[/]*\)*[*]*[*][/]\)\?\([\n][\n]*\([/][*][ ]Microcode[/]*\([*]*[^*/][^*/]*[/]*\)*[*]*[*][/][\n]*\)\?static[ ]\(u\(nsigned[ ]\)\?char\|unsigned[ ]short\|ADV_DCNT\)[ ]_\(asc_mcode\|adv_asc3\(550\|8C\(08\|16\)00\)\)_\(buf\[\][ ]=[ ][{][^}]*[}]\|size[ ]=[ ]sizeof[^;]*\|chksum[ ]=[ ]0x[^;]*\)[;]\([ ]*[/][*][/]*\([*]*[^*/][^*/]*[/]*\)*[*]*[*][/]\)\?\)*' drivers/scsi/advansys.c
+ blob '\([/][*][ ]Microcode[/]*\([*]*[^*/][/]*\)*[*]*[*][/][\n]*\)\?static[ ]\(u\(nsigned[ ]\)\?char\|unsigned[ ]short\|ADV_DCNT\)[ ]_\(asc_mcode\|adv_asc3\(550\|8C\(08\|16\)00\)\)_\(buf\[\][ ]=[ ][{][^}]*[}]\|size[ ]=[ ]sizeof[^;]*\|chksum[ ]=[ ]0x[^;]*\)[;]\([ ]*[/][*][/]*\([*]*[^*/][/]*\)*[*]*[*][/]\)\?\([\n][\n]*\([/][*][ ]Microcode[/]*\([*]*[^*/][/]*\)*[*]*[*][/][\n]*\)\?static[ ]\(u\(nsigned[ ]\)\?char\|unsigned[ ]short\|ADV_DCNT\)[ ]_\(asc_mcode\|adv_asc3\(550\|8C\(08\|16\)00\)\)_\(buf\[\][ ]=[ ][{][^}]*[}]\|size[ ]=[ ]sizeof[^;]*\|chksum[ ]=[ ]0x[^;]*\)[;]\([ ]*[/][*][/]*\([*]*[^*/][/]*\)*[*]*[*][/]\)\?\)*' drivers/scsi/advansys.c
blob '\(#ifdef[ ]UNIQUE_FW_NAME[\n]\)\?static[ ]unsigned[ ]short[ ]\(risc\|fw12\(80e\|160\)i\)_code01\[\][ ]=[ ][{]\([\n]#else[\n]static[ ]unsigned[ ]short[ ]risc_code01\[\][ ]=[ ][{][\n]#endif[\n]\)\?[^}]*[}][;]\([\n][\n]*\(#ifdef[ ]UNIQUE_FW_NAME[\n]\)\?static[ ]unsigned[ ]short[ ]\(risc_code\|fw12\(80e\|160\)i\)_length01[ ]=[ ][^;]*[;]\([\n]#else[\n]static[ ]unsigned[ ]short[ ]risc_code_length01[ ]=[ ][^;]*[;][\n]#endif\)\?\)\?' 'drivers/scsi/ql1\(04\|2\(8\|16\)\)0_fw\.h'
blobname 'keyspan[/]\(mpr\|usa\(18x\|19\(q[iw]\|w\)\?\|28\(x\(a\|b\)\?\)\?\|49w\(lc\)\?\)\)\.fw' drivers/usb/serial/keyspan.c
accept '[ ][ ]fw_name[ ]=[ ]["]keyspan_pda[/]\(keyspan_pda\|xircom_pgs\)\.fw["][;]' drivers/usb/serial/keyspan_pda.c
- blobna 'fw_name[ ]=[ ]\([^}]\|[^\n}][}]*\)*\([/][*]KEYSPAN_PDA[*][/]\)\?request_ihex_firmware' drivers/usb/serial/keyspan_pda.c
+ blobna 'fw_name[ ]=[ ]\([\n]*[^\n}][}]*\)*\([/][*]KEYSPAN_PDA[*][/]\)\?request_ihex_firmware' drivers/usb/serial/keyspan_pda.c
accept '[ ]if[ ][(][/][*]KEYSPAN_PDA[*][/]request_ihex_firmware' drivers/usb/serial/keyspan_pda.c
blobname 'edgeport[/]\(boot\|down\)2\?\.fw' drivers/usb/serial/io_edgeport.c
blobname 'cyzfirm\.bin' drivers/char/cyclades.c
accept 'MODULE_FIRMWARE[(]["]dsp56k[/]bootstrap\.bin["][)][;]' drivers/char/dsp56k.c
- blobna 'const[ ]char[ ]fw_name\[\][ ]=[ ]["]dsp56k[/]bootstrap\.bin["][;]\([^}]\|[^\n}][}]*\)*request_firmware\([^}]\|[^\n}][}]*\)*[\n][ ]err[ ]=[ ]request_firmware[(][&]fw,[ ]fw_name,[ ]' drivers/char/dsp56k.c
- accept '[ ]const[ ]char[ ]fw_name\[\][ ]=[ ]["]dsp56k[/]bootstrap\.bin["][;]\([^}]\|[^\n}][}]*\)*[\n][ ]err[ ]=[ ]request_firmware[(][&]fw,[ ]fw_name,[ ]' drivers/char/dsp56k.c
+ blobna 'const[ ]char[ ]fw_name\[\][ ]=[ ]["]dsp56k[/]bootstrap\.bin["][;]\([\n]*[^\n}][}]*\)*request_firmware\([\n]*[^\n}][}]*\)*[\n]\+[ ]err[ ]=[ ]request_firmware[(][&]fw,[ ]fw_name,[ ]' drivers/char/dsp56k.c
+ accept '[ ]const[ ]char[ ]fw_name\[\][ ]=[ ]["]dsp56k[/]bootstrap\.bin["][;]\([\n]*[^\n}][}]*\)*[\n]\+[ ]err[ ]=[ ]request_firmware[(][&]fw,[ ]fw_name,[ ]' drivers/char/dsp56k.c
blobname 'isi\(6\(08\|\(08\|16\)em\)\|46\(08\|16\)\)\.bin' drivers/char/isicom.c
blobname 'dvb-fe-xc5000-1\.1\.fw' drivers/media/common/tuners/xc5000.c
blobname '4210\(100[12]\|%4X\)\.sb' drivers/net/irda/irda-usb.c
- blobna '[/][*][ \n*]*[ ]Known[ ]firmware[/]*\([*]*[^*/][^*/]*[/]*\)*[*]*\(STIR421x\|4210\(100[12]\|%4X\)\.sb\)[/]*\([*]*[^*/][^*/]*[/]*\)*[*]*[*][/]' drivers/net/irda/irda-usb.c
+ blobna '[/][*][ \n*]*[ ]Known[ ]firmware[/]*\([*]*[^*/][/]*\)*[*]*\(STIR421x\|4210\(100[12]\|%4X\)\.sb\)[/]*\([*]*[^*/][/]*\)*[*]*[*][/]' drivers/net/irda/irda-usb.c
blobname 'myri10ge_\(rss_\)\?ethp\?_z8e\.dat' drivers/net/myri10ge.c
- blobna 'If[ ]the[ ]driver[ ]can[ ]neither[ ]enable[ ]ECRC[/]*\([*]*[^*/][^*/]*[/]*\)*[*]*myri10ge_\(rss_\)\?ethp\?_z8e\.dat[/]*\([*]*[^*/][^*/]*[/]*\)*[*]*[*][/]' drivers/net/myri10ge.c
+ blobna 'If[ ]the[ ]driver[ ]can[ ]neither[ ]enable[ ]ECRC[/]*\([*]*[^*/][/]*\)*[*]*myri10ge_\(rss_\)\?ethp\?_z8e\.dat[/]*\([*]*[^*/][/]*\)*[*]*[*][/]' drivers/net/myri10ge.c
blobname 'spider_fw\.bin' drivers/net/spider_net.h
blobna 'if[ ][(]IPW2100_FW_MAJOR[^{]*[{][^}]*[ ][}]' 'drivers/net/wireless/\(ipw2x00/\)\?ipw2100\.c'
blobname '["]["][ ]x[ ]["]\.fw["]' 'drivers/net/wireless/\(ipw2x00/\)\?ipw2100\.c'
- accept '[/][*][ ]Call[ ]this[ ]function[ ]from[ ]process[ ]context[/]*\([*]*[^*/][^*/]*[/]*\)*[*]*request_firmware' 'drivers/net/wireless/\(ipw2x00/\)\?ipw2200.c'
+ accept '[/][*][ ]Call[ ]this[ ]function[ ]from[ ]process[ ]context[/]*\([*]*[^*/][/]*\)*[*]*request_firmware' 'drivers/net/wireless/\(ipw2x00/\)\?ipw2200.c'
blobname 'ipw2200-\(i\?bss\|sniffer\)\.fw' 'drivers/net/wireless/\(ipw2x00/\)\?ipw2200.c'
accept '[ ][ ]IPW_ERROR[(]["]%s[ ]request_firmware[ ]failed' 'drivers/net/wireless/\(ipw2x00/\)\?ipw2200.c'
blobname 'sd\(8385\|868[68]\)\(_helper\)\?\.bin' drivers/net/wireless/libertas/if_sdio.c
accept '[ ]*card->firmware[ ]=[ ]\(if_sdio\|lbs_fw\)' drivers/net/wireless/libertas/if_sdio.c
blobname 'usb8388\(-5\.126\.0\.p5\)\?\.bin' drivers/net/wireless/libertas/if_usb.c
- blob '[/][*][/]*\([*]*[^*/][^*/]*[/]*\)*[*]*usb8388\(-5\.126\.0\.p5\)\?\.bin[/]*\([*]*[^*/][^*/]*[/]*\)*[*]*[*][/]' drivers/net/wireless/libertas/if_usb.c
+ blob '[/][*][/]*\([*]*[^*/][/]*\)*[*]*usb8388\(-5\.126\.0\.p5\)\?\.bin[/]*\([*]*[^*/][/]*\)*[*]*[*][/]' drivers/net/wireless/libertas/if_usb.c
accept '[ ][ ]lbs_pr_err[(]["]request_firmware\([(][)]\)\?[ ]failed' 'drivers/net/wireless/if_\(spi\|usb\)\.c'
blobna 'o\.[ ]Copy[ ]the[ ]firmware[ ]image[^\n]*usb8388\([^\n]\|[\n][ ]*[^ \n]\)*' drivers/net/wireless/libertas/README
blobna '\[fw_name=usb8388[^]]*\]' drivers/net/wireless/libertas/README
blobname 'lbtf_usb\.bin' drivers/net/wireless/libertas_tf/if_usb.c
blobname 'isl38\(86\|87\|90\)\(usb\(_bare\)\?\)\?' 'drivers/net/wireless/p54/p54\(pci\.c\|usb\.[ch]\)'
- blob '[/][*][ ]for[ ]isl3886[ ]register[ ]definitions[/]*\([*]*[^*/][^*/]*[/]*\)*[*]*[*][/]' drivers/net/wireless/p54/p54usb.h
+ blob '[/][*][ ]for[ ]isl3886[ ]register[ ]definitions[/]*\([*]*[^*/][/]*\)*[*]*[*][/]' drivers/net/wireless/p54/p54usb.h
blobna 'If[ ]you[ ]enable[ ]this\([^\n]\|[\n][ ]*[^ \n]\)*isl3890\([^\n]\|[\n][ ]*[^ \n]\)*' drivers/net/wireless/Kconfig
blobname 'isl38\(77\|86\|90\)' drivers/net/wireless/prism54/islpci_dev.c
blobname 'aica_firmware\.bin' sound/sh/aica.c
- accept '[ ][*][/]*\([*]*[^*/][^*/]*[/]*\)*[*]*Caution:[ ]This[ ]API[/]*\([*]*[^*/][^*/]*[/]*\)*[*]*request_firmware.' sound/sound_firmware.c
+ accept '[ ][*][/]*\([*]*[^*/][/]*\)*[*]*Caution:[ ]This[ ]API[/]*\([*]*[^*/][/]*\)*[*]*request_firmware.' sound/sound_firmware.c
accept 'static[ ]int[ ]do_mod_firmware_load[(]' sound/sound_firmware.c
accept 'int[ ]mod_firmware_load[(]' sound/sound_firmware.c
accept '[ ]r[ ]=[ ]do_mod_firmware_load[(]' sound/sound_firmware.c
blobname 'dvb-fe-nxt2002\.fw' drivers/media/dvb/frontends/nxt200x.c
- blob '[/][*][\n][ ][*][ ]This[ ]driver[ ]needs[ ]two[ ]external[ ]firmware[ ]files[/]*\([*]*[^*/][^*/]*[/]*\)*[*]*dvb-fe-or51132-\(vsb\|qam\)\.fw[/]*\([*]*[^*/][^*/]*[/]*\)*[*]*[*][/]' drivers/media/dvb/frontends/or51132.c
+ blob '[/][*][\n][ ][*][ ]This[ ]driver[ ]needs[ ]two[ ]external[ ]firmware[ ]files[/]*\([*]*[^*/][/]*\)*[*]*dvb-fe-or51132-\(vsb\|qam\)\.fw[/]*\([*]*[^*/][/]*\)*[*]*[*][/]' drivers/media/dvb/frontends/or51132.c
blobname 'dvb-fe-or51132-\(vsb\|qam\)\.fw' drivers/media/dvb/frontends/or51132.c
blobname 'dvb-fe-or51211\.fw' drivers/media/dvb/frontends/or51211.c
# These are regarded as ok
initnc 'static[ ]const[ ]u8[ ]SN9C102_\(Y\|UV\)_QTABLE[01]\[64\][ ]=[ ][{]'
initnc '[ ]static[ ]\(const[ ]\)\?u8[ ]jpeg_header\[589\][ ]=[ ][{]' media/video/sn9c102/sn9c102_core.c
- accept '[ ]\{1,2\}err[ ]=[ ]sn9c102_write_const_regs[(]cam\(,[ \n]\+[{]0x[0-9a-fA-F][0-9a-fA-F],[ ]0x[0-9a-fA-F][0-9a-fA-F][}]\)*[)][;]'
+ accept '[ ][ ]\?err[ ]=[ ]sn9c102_write_const_regs[(]cam\(,[ \n]\+[{]0x[0-9a-fA-F][0-9a-fA-F],[ ]0x[0-9a-fA-F][0-9a-fA-F][}]\)*[)][;]'
# too lax?
defsnc 'static[ ]yyconst[ ]\(flex_int\(16\|32\)_t\|\(\(short[ ]\)\?int\)\)[ ]yy_[^[]*\[[][0-9]*\][ ]='
defsnc 'static[ ]struct[ ]nand_ecclayout[ ]onenand_oob_128[ ]=' drivers/mtd/onenand/onenand_base.c
blobname 'bnx2x-e1h\?-\([0-9.%d]*\.fw\)\?' drivers/net/bnx2x_main.c
blob '#define[ ]BCM_5710_FW_\(\(MAJOR\|MINOR\|REVISION\|ENGINEERING\)_VERSION\|COMPILE_FLAGS\)[ ]*[0-9]\+\([\n]#define[ ]BCM_5710_FW_\(\(MAJOR\|MINOR\|REVISION\|ENGINEERING\)_VERSION\|COMPILE_FLAGS\)[ ]*[0-9]\+\)*' drivers/net/bnx2x_hsi.h
- blob 'static[ ]int[ ]__devinit[ ]bnx2x_check_firmware[(]struct[ ]bnx2x[ ][*]bp[)][\n][{]\([^}]\|[^\n}][}]*\)*[\n][}]' drivers/net/bnx2x_main.c
+ blob 'static[ ]int[ ]__devinit[ ]bnx2x_check_firmware[(]struct[ ]bnx2x[ ][*]bp[)][\n][{]\([\n]*[^\n}][}]*\)*[\n]\+[}]' drivers/net/bnx2x_main.c
blobna 'if[ ][(][(]fw_ver\[[0-3]\][ ]!=[ ]BCM_5710_FW_\(MAJOR\|MINOR\|REVISION\|ENGINEERING\)_VERSION[)]\([ ][|][|][\n][ ]*[(]fw_ver\[[0-3]\][ ]!=[ ]BCM_5710_FW_\(MAJOR\|MINOR\|REVISION\|ENGINEERING\)_VERSION[)]\)*[)][ ][{][^{}]*[}]' drivers/net/bnx2x_main.c
blobna 'sprintf[(]fw_file_name[ ][+][ ]offset,[ ]["]%d[.]%d[.]%d[.]%d[.]fw["]\(,[\n][ ]*BCM_5710_FW_\(MAJOR\|MINOR\|REVISION\|ENGINEERING\)_VERSION\)*[)][;]' drivers/net/bnx2x_main.c
blob 'rc[ ]=[ ]bnx2x_check_firmware[(]bp[)][;]' drivers/net/bnx2x_main.c
defsnc '[ ][}][ ]common_modes\[17\][ ]=' drivers/gpu/drm/radeon/radeon_connectors.c
defsnc '[ ][ ]*\(static[ ]\)\?struct[ ]phy_reg[ ]phy_reg_init\(_0\)\?\[\][ ]=' drivers/net/r8169.c
accept '[ ][ ]*struct[ ]phy_reg[ ]phy_reg_init_1\[\][ ]=[ ][{][^;]*0x8300[^;]*[}][;]' drivers/net/r8169.c
- blob 'static[ ]void[ ]rtl8168d_[12]_hw_phy_config[(]void[ ]__iomem[ ][*]ioaddr[)][\n][{][\n]\([^}]*\|[^\n}][}]*\)*[\n][}]' drivers/net/r8169.c
+ blob 'static[ ]void[ ]rtl8168d_[12]_hw_phy_config[(]void[ ]__iomem[ ][*]ioaddr[)][\n][{][\n]\([\n]*[^\n}][}]*\)*[\n]\+[}]' drivers/net/r8169.c
blobna 'rtl8168d_[12]_hw_phy_config[(]ioaddr[)][;]' drivers/net/r8169.c
blobna 'static[ ]struct[ ]phy_reg_init_[12]\[\][ ]=[ ][{][\n {}0-9a-fx]*0x06,[ ]0xf8f9[\n {}0-9a-fx]*[}][;]' drivers/net/r8169.c
# This loads firmware to be flashed from filename provided through ethtool.
- accept 'int[ ]be_load_fw[(][^\n;{]*[)][ \n][{]\([^}]*\|[^\n}][}]*\)*ETHTOOL_FLASH_MAX_FILENAME\([^}]*\|[^\n}][}]*\)*be_cmd_get_fw_ver\([^}]*\|[^\n}][}]*\)*request_firmware\([^}]*\|[^\n}][}]*\)*[\n][}]' drivers/net/benet/be_main.c
+ accept 'int[ ]be_load_fw[(][^\n;{]*[)][ \n][{]\([\n]*[^\n}][}]*\)*ETHTOOL_FLASH_MAX_FILENAME\([\n]*[^\n}][}]*\)*be_cmd_get_fw_ver\([\n]*[^\n}][}]*\)*request_firmware\([\n]*[^\n}][}]*\)*[\n]\+[}]' drivers/net/benet/be_main.c
defsnc '[ ]u8[ ]init_hash_seed\[\][ ]=' drivers/net/qlge/qlge_main.c
defsnc 'static[ ]const[ ]u_int32_t[ ]ar9287\(Common\|Modes\(_\([tr]x_gain\)\)\?\)_9287_1_[01]\[\]\[[236]\][ ]=' drivers/net/wireless/ath9k/initvals.h
defsnc 'static[ ]const[ ]u_int32_t[ ]ar9271\(Common\|Modes\)_9271_1_0\[\]\[[26]\][ ]=' drivers/net/wireless/ath9k/initvals.h
defsnc 'static[ ]struct[ ]nand_ecclayout[ ]hwecc4_2048[ ]__initconst[ ]=' drivers/mtd/nand/davinci_nand.c
defsnc 'static[ ]const[ ]u16[ ]wm8974_reg\[WM8974_CACHEREGNUM\][ ]=' sound/soc/codecs/wm8974.c
defsnc 'static[ ]const[ ]u16[ ]ak4642_reg\[AK4642_CACHEREGNUM\][ ]=' sound/soc/codecs/ak4642.c
- accept 'int[ ]snd_hda_load_patch[(][^\n;{]*[)][ \n][{]\([^}]*\|[^\n}][}]*\)*hda_codec\([^}]*\|[^\n}][}]*\)*request_firmware\([^}]*\|[^\n}][}]*\)*[\n][}]' sound/pci/hda/hda_hwdep.c
+ accept 'int[ ]snd_hda_load_patch[(][^\n;{]*[)][ \n][{]\([\n]*[^\n}][}]*\)*hda_codec\([\n]*[^\n}][}]*\)*request_firmware\([\n]*[^\n}][}]*\)*[\n]\+[}]' sound/pci/hda/hda_hwdep.c
accept '[ ][ ][ ]Bit[ 0-7]*' Documentation/input/sentelic.txt
accept 'The[ ]hd-audio[ ]driver[ ]reads[ ]the[ ]file[ ]via[ ]request_firmware[(][)]\.' Documentation/sound/alsa/HD-Audio.txt
blob 'SD8688[ ]firmware:[\n]*\([/]lib[/]firmware[^\n]*[\n]*\)*The[ ]images[^:]*:[\n]*[^\n]*[/]linux-firmware[^\n]*' Documentation/btmrvl.txt
defsnc 'static[ ]int[ ]zoom2_batt_table\[\][ ]=' arch/arm/mach-omap2/board-zoom2.c
defsnc 'static[ ]struct[ ]ad714x_platf\(or\|ro\)m_data[ ]ad714[27]_platf\(or\|ro\)m_data[ ]=' arch/blackfin/mach-bf537/boards/stamp.c
blob 'static[ ]const[ ]u8[ ]lgs8g75_initdat\[\][ ]=[ ][{][^;]*[}][;]' drivers/media/dvb/frontends/lgs8gxx.c
- blob 'static[ ]int[ ]lgs8g75_init_data[(][^\n;{]*[)][ \n][{]\([^}]*\|[^\n}][}]*\)*lgs8g75_initdat\([^}]*\|[^\n}][}]*\)*[\n][}]' drivers/media/dvb/frontends/lgs8gxx.c
+ blob 'static[ ]int[ ]lgs8g75_init_data[(][^\n;{]*[)][ \n][{]\([\n]*[^\n}][}]*\)*lgs8g75_initdat\([\n]*[^\n}][}]*\)*[\n]\+[}]' drivers/media/dvb/frontends/lgs8gxx.c
defsc 'static[ ]struct[ ]idxdata[ ]tbl_common_[a-e]\[\][ ]=' 'drivers/media/video/gspca/gl860/gl860-\(mi2020\|mi1320\|ov9655\|ov2640\)\.c'
defsnc 'static[ ]struct[ ]validx[ ]tbl_\(commm\?on\|init_\(at_startup\|post_alt\)\|sensor_settings_common_[ab]\|big_[abc]\|640\|800\)\[\][ ]=' 'drivers/media/video/gspca/gl860/gl860-\(mi2020\|mi1320\|ov9655\|ov2640\).c'
defsnc 'static[ ]u8[ ][*]tbl_\(640\|800\)\[\][ ]=' 'drivers/media/video/gspca/gl860/gl860-\(mi1320\|ov9655\).c'
constx="[0-9][0-9a-fA-FxX]*"
# Regular expression that matches a separator between consecutive
# literal constants.
-sepx="\\([,:{} \\nLlUu\"\'\\\\]\\+[xX\$]\\?\\|[ \\n]*[.][a-zA-Z][a-zA-Z0-9]*[ ]\\+[\$]\\?\\)"
+sepx="\\([ \\n]*\\(\\([ \\n]\\|[,:{}LlUu\"\'\\\\][,:{} \\nLlUu\"\'\\\\]*\\)[xX\$]\\?\\|[.][a-zA-Z][a-zA-Z0-9]*[ ]\\+[\$]\\?\\)\\)"
# Regular expression that matches a continuation of a blob, after an
# initial constant. *, \+ and \? can be safely appended to it without
eol="\\([\\n]\\|\$\\)"
# Regular expression that matches a C-style comment.
-comment="\\([/][*][/]*\\([*]*[^*/][^*/]*[/]*\\)*[*]*[*][/]\\|[/][/][^\\n]*[\\n]\\)"
+comment="\\([/]\\([*][/]*\\([*]*[^*/][/]*\\)*[*]\\+[/]\\|[/][^\\n]*[\\n]\\)\\)"
# Regular expression that matches comments typically used in assembly.
asmcomment="\\($comment\\|[;#][^\\n]*[\\n]\\)"
# Regular expression that matches a braced initializer containing at
# least one blob.
-initblob="[^\\n]*=\\([ \\n\\\\]*\\|$comment\\)*[{]\\([^;]*\\|$comment\\)*$blobseq\\([^;]*\\|$comment\\)*[}]\\?\\([ \\n\\\\]*\\|$comment\\)[;]\\?"
+initblob="[^\\n=]*=\\([ \\n\\\\]\\|$comment\\)*[{]\\([^;]\\|$comment\\)*$blobseq\\([^;]\\|$comment\\)*[}]\\?\\([ \\n\\\\]*\\|$comment\\)[;]\\?"
# Regular expression that matches a C (possibly multi-line) #define
# that contains a blob.
-defineblob='[ ]*#[ ]*define[ ]\+\([^\n]*\\[\n]\)*[^\n]*'"$blobseq"'\([^\n]*\\[\n]\)*'
+defineblob='[ ]*#[ ]*define[ ][^\n]*\([\\][\n][^\n]*\)*'"$blobseq"'\([^\n]*\\[\n]\)*'
# Regular expression that matches an assembly label followed by a blob
# without any intervening label.
-asmblob="[a-zA-Z_.][^\\n:;#/ ]*[ ]*:\\([^:{}]*\\|$asmcomment\\)*$blobseq\\([^:]*\\|$asmcomment\\)*"
+asmblob="[a-zA-Z_.][^\\n:;#/ ]*:\\([^:{}]\\|$asmcomment\\)*$blobseq\\([^:]*\\|$asmcomment\\)*"
# Set up the sed script that will go through the (processed) input,
# looking for sequences of blobs and printing whatever was requested.
# $4 is the action for every complete input pattern.
set_sed_main () {
- falsepos=`sed -n 's,^[+]\^*,,p' < "$regex_name" |
- sed -n -e 's,[$]$,\\\\([\\\\n]\\\\|$\\\\),' \
+ falsepos=`${SED-sed} -n 's,^[+]\^*,,p' < "$regex_name" |
+ ${SED-sed} -n -e 's,[$]$,\\\\([\\\\n]\\\\|$\\\\),' \
-e '1h; 1!H; ${g;s,[\n],\\\\|,g;s,^\(..*\)$,\\\\(\1\\\\),;p;}'`
- blobs=`sed -n 's,^[-],,p' < "$regex_name" |
- sed -n -e 's,[$]$,\\\\([\\\\n]\\\\|$\\\\),' \
+ blobs=`${SED-sed} -n 's,^[-],,p' < "$regex_name" |
+ ${SED-sed} -n -e 's,[$]$,\\\\([\\\\n]\\\\|$\\\\),' \
-e '1h; 1!H; ${g;s,[\n],\\\\|,g;s,^\(..*\)$,\\\\(\1\\\\),;p;}'`
# Regular expression that matches one or more blobs without
" > "$scriptname"
- scriptcmd='$sed -n -f "$scriptname"'
+ scriptcmd='${SED-sed} -n -f "$scriptname"'
sedunbreak='
: restart
}
p
'
- scriptcmd2='$sed -n -e "$sedunbreak"'
+ scriptcmd2='${SED-sed} -n -e "$sedunbreak"'
}
set_flex_main () {
'
echo '%%' > "$scriptname"
- sed "$adjust_rx" < "$regex_name" >> "$scriptname"
+ ${SED-sed} "$adjust_rx" < "$regex_name" >> "$scriptname"
echo '\n|. { unmatched (); }
%%
int falsepos () {}
EOF
if test "X$DEBLOB_CHECK_PYTHON_REGEX" = Xdebug; then
- sed -e "$adjust_rx" \
+ ${SED-sed} -e "$adjust_rx" \
-e 's,\([^-+]*\)\(.*\),re.compile (r'"'\\2'"'),g' \
< "$regex_name" >> "$scriptname"
fi
- sed -n 's,^[+],,p' < "$regex_name" |
- sed -n -e "$adjust_rx" -e 's,\^,,' \
+ ${SED-sed} -n 's,^[+],,p' < "$regex_name" |
+ ${SED-sed} -n -e "$adjust_rx" -e 's,\^,,' \
-e '1h; 1!H; $ { g; s,[\n],|,g; '"\
s,^\\(.*\\)\$,falsepos = r'(?P<falsepos>\\1)',;\
"' p;}' >> "$scriptname"
- sed -n 's,^[-],,p' < "$regex_name" |
- sed -n -e "$adjust_rx" \
+ ${SED-sed} -n 's,^[-],,p' < "$regex_name" |
+ ${SED-sed} -n -e "$adjust_rx" \
-e '1h; 1!H; $ { g; s,[\n],|,g; '"\
s,^\\(.*\\)\$,blob = r'(?P<blob>\\1)',;\
"' p;}' >> "$scriptname"
echo "\\($initblob\\|$defineblob\\|$asmblob\\)" |
- sed -e "$adjust_rx" \
+ ${SED-sed} -e "$adjust_rx" \
-e "s,^\\(.*\\)\$,cblob = r'(?P<cblob>\\1)'," >> "$scriptname"
cat >> "$scriptname" <<\EOF
if no_falsepos or falsepos is None:
falsepos = r'(?!)'
-# Use non-greedy operator to skip partial line before blob, to avoid
-# skipping blobs when more than one appears in the same line.
-rx = '^%s|[^\n]*?%s' % (falsepos, blob)
+rx = '^%s|%s' % (falsepos, blob)
if with_context:
rx += '|^' + cblob
-rxc = re.compile(rx, re.M | re.S)
+rxc = re.compile('(?<=.)(?:%s)' % rx, re.M | re.S)
filenames = None
-s = ''
+s = '\n'
for line in sys.stdin:
# Read into s all lines between begin and end. An empty line, without
if line[:3] == ';/*' and line[-4:] == '*/;\n':
if line[3:9] == 'begin ':
nextfilenames = (line[9:-4], filenames)
- if s == '':
+ if s == '\n':
filenames = nextfilenames
del nextfilenames
continue
s += line
continue
else:
- assert filenames != None
+ assert filenames != None
s += line
continue
print 'looking for matches'
sfilenames = filenames
while filenames != None:
- if filenames[0] == name_to_list:
+ if filenames[0] == name_to_list:
print name_to_list
assert filenames[1] == None
else:
if s[-1] == '\n':
s = s[:-1]
- pp = p = pend = 0
+ pp = 1
+ p = pend = 0
match = rxc.search (s, p)
while match != None:
firstmatch = match
blobs = falses = 0
- while match != None:
+ while 1:
if verbose:
print 'found match'
what = match.lastgroup
if what == 'cblob':
- if verbose: print 'match is a blob context'
- pend = match.end()
+ if verbose: print 'match is a blob context'
+ pend = s.find ('\n', match.end()) + 1
+ if pend == 0:
+ pend = len(s)
p = match.start() + 1
- match = rxc.search (s, p)
- continue
-
- blob_p = what == 'blob'
- assert blob_p or what == 'falsepos'
-
- if blob_p:
- if verbose: print 'match is a blob'
- blobs += 1
else:
- if verbose: print 'match is a false positive'
- falses += 1
+ blob_p = what == 'blob'
+ assert blob_p or what == 'falsepos'
+
+ if blob_p:
+ if verbose: print 'match is a blob'
+ blobs += 1
+ else:
+ if verbose: print 'match is a false positive'
+ falses += 1
- assert match.end(what) == match.end()
- if blob_p and replace_blob or not blob_p and replace_falsepos:
- s = s[:match.start(what)] + replacement + s[match.end():]
- p = match.start(what) + len(replacement)
- else:
- p = match.end()
+ if blob_p and replace_blob or not blob_p and replace_falsepos:
+ s = s[:match.start(what)] + replacement + s[match.end(what):]
+ p = match.start(what) + len(replacement)
+ if pend > match.start(what):
+ pend += p - match.end(what)
+ else:
+ p = match.end(what)
- match = rxc.match (s, p)
-
- if print_nomatch:
- sys.stdout.write (s[pp:firstmatch.start()])
- pp = firstmatch.start()
+ if p > pend:
+ pend = s.find ('\n', p) + 1
+ if (pend == 0):
+ pend = len(s)
- if (p < pend):
- p = pend
+ match = rxc.search (s, p)
+ if match == None or match.start () >= pend:
+ break
- p = s.find ('\n', p)
- if p == -1:
- p = len(s)
- p += 1
+ if print_nomatch:
+ sys.stdout.write (s[pp:firstmatch.start() + 1])
+ pp = firstmatch.start() + 1
+ else:
+ pp = s.rfind ('\n', 0, firstmatch.start () + 1) + 1
if print_blob and blobs or print_falsepos and falses:
if not print_nomatch:
assert filenames[1] != None
filenames = filenames[1]
filenames = sfilenames
- sys.stdout.write (s[pp:p])
- pp = p
+ sys.stdout.write (s[pp:pend])
+ pp = pend
if list_blob and blobs or list_falsepos and falses:
while filenames != None:
- if filenames[0] == name_to_list:
+ if filenames[0] == name_to_list:
print name_to_list
assert filenames[1] == None
else:
filenames = filenames[1]
exit (1)
- match = rxc.search (s, p)
-
if print_nomatch:
sys.stdout.write(s[pp:])
if verbose:
print 'no further matches'
- s = ''
+ s = '\n'
filenames = nextfilenames
del nextfilenames
scriptcmd="${PYTHON-python} "'"$scriptname"'
}
+set_perl_main () {
+ adjust_rx='
+s,\\(,\\(?:,g;
+s,\\\([{(|)}?+]\),\1,g;
+'
+
+ # Add $ before arguments
+ set `echo "$@" | sed 's,\(^\|= *\),&$,g'`
+
+ cat >> "$scriptname" <<\EOF
+#! /usr/bin/perl
+
+use strict;
+use warnings;
+
+# Should we replace blobs and false positives with replacement?
+my $replace_blob = 0;
+my $replace_falsepos = 0;
+my $replacement = '/*(DEBLOBBED)*/';
+
+# Should we print lines containing blobs, false positives, and neither?
+my $print_blob = 0;
+my $with_context = 0;
+my $print_falsepos = 0;
+my $print_nomatch = 0;
+
+# Should we print name_to_list and exit if we find blobs or false positives?
+my $list_blob = 0;
+my $list_falsepos = 0;
+
+# Should we forget everything we know about false positives?
+my $falsepos;
+my $no_falsepos = 0;
+
+EOF
+
+ cat >> "$scriptname" <<EOF
+my \$name_to_list = '$input';
+
+my \$verbose = $vp;
+
+# Which of the defaults above should we override?
+$@ = 1;
+
+EOF
+
+ ${SED-sed} -n 's,^[+],,p' < "$regex_name" |
+ ${SED-sed} -n -e "$adjust_rx" -e 's,\^,,' \
+ -e '1h; 1!H; $ { g; s,[\n],|,g; '"\
+s,^\\(.*\\)\$,\$falsepos = qr'(?<falsepos>\\1)'ms;,;\
+"' p;}' >> "$scriptname"
+
+ ${SED-sed} -n 's,^[-],,p' < "$regex_name" |
+ ${SED-sed} -n -e "$adjust_rx" \
+ -e '1h; 1!H; $ { g; s,[\n],|,g; '"\
+s,^\\(.*\\)\$,my \$blob = qr'(?<blob>\\1)'ms;,;\
+"' p;}' >> "$scriptname"
+
+ echo "\\($initblob\\|$defineblob\\|$asmblob\\)" |
+ ${SED-sed} -e "$adjust_rx" \
+ -e "s,^\\(.*\\)\$,my \$cblob = qr'(?<cblob>\\1)'ms if \$with_context;," >> "$scriptname"
+
+ cat >> "$scriptname" <<\EOF
+
+$falsepos = qr/(?<falsepos>(?!))/ if $no_falsepos || ! defined $falsepos;
+
+my $rx = qr/^$falsepos|$blob/ms;
+
+$rx = qr/$rx|^$cblob/ms if $with_context;
+
+my @filenames;
+my $nfilenames = 0;
+my $nextnfilenames;
+
+my $s = '';
+
+while (<STDIN>) {
+ # Read into s all lines between begin and end. An empty line, without
+ # even the '\n', flags the end of the input.
+ if (m:^[;][/][*](begin|end) (.*)[*][/][;]$:) {
+ if ($1 eq 'begin') {
+ print "entering $2\n" if $verbose;
+ $filenames[$nfilenames] = $2;
+ $nextnfilenames = $nfilenames + 1;
+ if ($s eq '') {
+ $nfilenames = $nextnfilenames;
+ next;
+ }
+ } else {
+ $nextnfilenames = $nfilenames - 1;
+ print "processing $filenames[$nextnfilenames]\n" if $verbose;
+ }
+ } else {
+ $s .= $_;
+ next;
+ }
+
+ if ($verbose) {
+ print "looking for matches in\n";
+ for (my $i = $nfilenames; --$i > 0; ) {
+ print $filenames[$i], " within\n";
+ }
+ print $filenames[0], "\n";
+ }
+
+ $s =~ s/[\n]$//;
+
+ my $pp = my $p = 0;
+
+ my $matchfound = substr ($s, $p) =~ /$rx/o;
+ while ($matchfound) {
+ print "found first match\n" if $verbose;
+ my $firstmatchstart = $-[0] + $p;
+ my $blobs = my $falses = 0;
+ my $matchstart = $-[0] + $p;
+ my $pend = -1;
+ my $blob_p;
+ do {{
+ my $matchend = $+[0] + $p;
+ print "found match $matchstart..$matchend\n" if $verbose;
+ print "$&" if $verbose > 1;
+
+ if (defined $+{'cblob'}) {
+ print "match is a blob context\n" if ($verbose);
+ $pend = index ($s, "\n", $matchend) + 1;
+ $pend = length $s if !$pend;
+ }
+
+ if (defined $+{'falsepos'}) {
+ print "match is a false positive\n" if ($verbose);
+ # $matchend -= $+[0] - $+[1];
+ $blob_p = 0;
+ $falses++;
+ } elsif (defined $+{'blob'}) {
+ $blob_p = 1;
+ $blobs++;
+ print "match is a blob at $matchstart\n" if ($verbose);
+ } else {
+ $p = $matchstart;
+ print "searching up to $pend\n" if $verbose;
+ next;
+ }
+
+ if ($blob_p ? $replace_blob : $replace_falsepos) {
+ substr ($s, $matchstart, $matchend - $matchstart,
+ $replacement);
+ $p = $matchstart + length $replacement;
+ $pend += $p - $matchend if $pend >= $matchstart;
+ } else {
+ $p = $matchend;
+ }
+
+ $pend = index ($s, "\n", $p) + 1 if $p >= $pend;
+ $pend = length $s if !$pend;
+ print "searching up to $pend\n" if $verbose;
+ $p--;
+ }} while (($matchfound = (substr ($s, $p) =~ /(?<=.)$rx/mso))
+ && ($matchstart = $-[0] + $p) < $pend);
+
+ print "last match before $pend\n" if $verbose;
+
+ if ($print_nomatch) {
+ print substr ($s, $pp, $firstmatchstart - $pp);
+ $pp = $firstmatchstart;
+ } elsif (($print_blob || $print_falsepos) && $firstmatchstart > 0) {
+ $pp = rindex ($s, "\n", $firstmatchstart - 1) + 1;
+ }
+
+ if (($print_blob && $blobs) || ($print_falsepos && $falses)) {
+ if (!$print_nomatch) {
+ for (my $i = $nfilenames; $i-- > 0;) {
+ print "::: ", $filenames[$i], " :::\n";
+ }
+ }
+
+ print substr ($s, $pp, $pend - $pp);
+ $pp = $pend;
+ }
+
+ if (($list_blob && $blobs) || ($list_falsepos && $falses)) {
+ for (my $i = $nfilenames; --$i > 0;) {
+ print $filenames[$i], " within ";
+ }
+ print $filenames[0], "\n";
+ exit (1);
+ }
+ }
+
+ print substr ($s, $pp) if $print_nomatch;
+
+ print "no further matches\n" if $verbose;
+
+ $s = '';
+ $nfilenames = $nextnfilenames;
+}
+
+exit (0);
+EOF
+
+ scriptcmd="${PERL-perl} "'"$scriptname"'
+}
+
set_awk_main () {
adjust_rx='
s,[$]$,([\\n]|$),;
case " = $@ = " in
*" = no_falsepos = "*) falsepos='$.^';;
*) falsepos=`
- sed -n 's,^[+],,p' < "$regex_name" |
- sed -n -e "$adjust_rx" -e 's,\^,,' \
+ ${SED-sed} -n 's,^[+],,p' < "$regex_name" |
+ ${SED-sed} -n -e "$adjust_rx" -e 's,\^,,' \
-e '1h; 1!H; $ { g; s,[\n],|,g; p;}'
`
case $falsepos in "") falsepos='$.^';; esac;;
esac
blob=`
- sed -n 's,^[-],,p' < "$regex_name" |
- sed -n -e "$adjust_rx" \
+ ${SED-sed} -n 's,^[-],,p' < "$regex_name" |
+ ${SED-sed} -n -e "$adjust_rx" \
-e '1h; 1!H; $ { g; s,[\n],|,g; p;}'`
case " = $@ = " in
*" = with_context = "*) cblob=`
$echo "\\($initblob\\|$defineblob\\|$asmblob\\)" |
- sed -e "$adjust_rx"
+ ${SED-sed} -e "$adjust_rx"
`;;
*) cblob='$.^';;
esac
verbose = $vp;
nfilenames = 0;
- s = "";
+ s = "\n";
# Which of the defaults above should we override?
$@ = 1;
# requires GNU awk RS extension:
-$xrs RS = "[;][/][*](begin|end) [^\n]*[*][/][;][\n]";
+$xrs RS = "[;][/][*](begin|end) [^\n]*[*][/][;][\n]";
}
# requires GNU awk RS extension:
$xrs { s = s \$0; }
# does not require GNU awk RS extension:
$nrs !/^[;][/][*].*[*][/][;]$/ {
-$nrs s = s \$0 "\n";
-$nrs next;
+$nrs s = s \$0 "\n";
+$nrs next;
$nrs }
$eormatch /^[;][/][*]begin .*[*][/][;]$eornl$/ {
filenames[nfilenames] = substr($eor, 10, length ($eor) - 12 - $eornlsz);
if (verbose) print "entering " nfilenames ": " filenames[nfilenames];
nextnfilenames = nfilenames + 1;
- if (s == "") {
+ if (s == "\n") {
nfilenames = nextnfilenames;
next;
}
{
if (verbose) {
print "looking for matches";
- for (i = nfilenames; --i >= 0;)
+ for (i = nfilenames; --i > 0;)
print filenames[i] " within";
- print filenames[0]
+ print filenames[0]
}
s = substr (s, 1, length (s) - 1)
- pp = p = pend = 1;
+ pp = 2;
+ p = pend = 1;
if (verbose > 1) print "searching starting at", substr (s, p, 10)
- while (match (substr (s, p),
- /(^|[\n])($falsepos)|(^|[\n])($cblob)|$blob/)) {
+ matchfound = match (substr (s, p),
+ /[\n]($falsepos)|[\n]($cblob)|.($blob)/);
+ while (matchfound) {
blobs = falses = 0;
- firstmatchstart = RSTART + p - 1;
- if (substr (s, firstmatchstart, 1) == "\n")
- firstmatchstart++;
+ firstmatchstart = RSTART + p;
for (;;) {
matchstart = RSTART + p - 1;
matchlen = RLENGTH;
- if (substr (s, matchstart, 1) == "\n") {
- matchstart++;
- matchlen--;
- }
- if (verbose)
+ if (verbose) {
print "found match", matchstart, matchlen;
- if (verbose > 1)
- print substr (s, matchstart, matchlen);
- if (match (substr (s, matchstart, matchlen), /^($falsepos)$/) == 1) {
+ if (verbose > 1)
+ print substr (s, matchstart + 1, matchlen - 1);
+ }
+
+ cblob_p = 0;
+
+ if (match (substr (s, matchstart, matchlen), /^[\n]($falsepos)/) == 1) {
if (verbose) print "match is a false positive";
blob_p = 0;
falses++;
- } else if (match (substr (s, matchstart, matchlen), /^($cblob)$/) == 1) {
+ } else if (match (substr (s, matchstart, matchlen), /^[\n]($cblob)$/) == 1) {
if (verbose) print "match is a blob context";
- pend = p + matchlen;
+ pend = index (substr (s, matchstart + matchlen), "\n");
+ if (pend)
+ pend += matchstart + matchlen;
+ else
+ pend = length (s);
p = matchstart + 1;
- if (verbose) print "search after cblob starting at", p;
- match (substr (s, p, matchlen - 1), /^($falsepos)|^($cblob)|[^\n]*($blob)/);
- continue;
+ if (verbose) print "range is:", substr (s, p, pend - p);
+ cblob_p = 1;
} else {
if (verbose) print "match is a blob";
blob_p = 1;
blobs++;
}
- if (blob_p ? replace_blob : replace_falsepos) {
- s = substr (s, 1, matchstart - 1) \\
- replacement \\
- substr (s, matchstart + matchlen);
- p = matchstart + length (replacement);
- } else
- p = matchstart + matchlen;
- i = index (substr (s, p), "\n");
- if (!i)
- i = length (s)
- p--;
- if (!match (substr (s, p),
- /[\n]($falsepos)|[\n]($cblob)|$blob/) \\
- || (RSTART > i && p + RSTART >= pend))
+ if (!cblob_p) {
+ if (blob_p ? replace_blob : replace_falsepos) {
+ s = substr (s, 1, matchstart) \\
+ replacement \\
+ substr (s, matchstart + matchlen);
+ p = matchstart + length (replacement) - 1;
+ pend += (p + 2 - matchstart - matchlen);
+ } else
+ p = matchstart + matchlen - 1;
+
+ if (p > pend) {
+ i = index (substr (s, p), "\n");
+ if (i)
+ pend = p + i;
+ else
+ pend = length (s)
+ }
+ }
+
+ if (verbose) print "search until", pend;
+
+ if (!(matchfound = match (substr (s, p),
+ /[\n]($falsepos)|[\n]($cblob)|.($blob)/)) ||
+ p + RSTART >= pend)
break;
}
if (print_nomatch)
printf "%s", substr (s, pp, firstmatchstart - pp);
- else if (print_blob || print_falsepos) {
+ else if (print_blob || print_falsepos) {
lastline = substr (s, pp, firstmatchstart - pp);
sub (/.*[\n]/, "", lastline);
+ if (verbose) print "lastline: " lastline "\\\\n"
firstmatchstart -= length (lastline);
- }
+ }
pp = firstmatchstart;
- if (p < pend)
- p = pend;
-
- i = index (substr (s, p), "\n");
- if (i)
- p += i;
- else
- p = length (s);
-
- if (verbose) print "match set range:", pp, p
+ if (verbose) print "match set range:", pp, pend
if ((print_blob && blobs) || (print_falsepos && falses)) {
if (!print_nomatch)
- for (i = nfilenames; i--;)
+ for (i = nfilenames; i-- > 0;)
print "::: " filenames[i] " :::";
- printf "%s", substr (s, pp, p - pp);
- pp = p;
+ printf "%s", substr (s, pp, pend - pp);
+ pp = pend;
}
if ((list_blob && blobs) || (list_falsepos && falses)) {
if (verbose)
print "no further matches";
- s = "";
+ s = "\n";
nfilenames = nextnfilenames;
next;
}
'
echo '%%' > "$scriptname"
- sed "$adjust_rx" < "$regex_name" >> "$scriptname"
+ ${SED-sed} "$adjust_rx" < "$regex_name" >> "$scriptname"
echo '\n|. { unmatched (); }
%%
int falsepos () {}
set_except "$input"
# Check that all regular expressions match our requirements.
- sed -n '
+ ${SED-sed} -n '
s,^\(-\^\?\|[+]\^\),,
h
s,[$]$,,
s/\$/*\\/;/
}
s/^[ $s]//"
- cmd='sed "$sedpatch"'
+ cmd='${SED-sed} "$sedpatch"'
;;
*)
cmd='cat'
+++ /dev/null
-#!/usr/bin/perl
- eval 'exec /usr/bin/perl -S $0 ${1+"$@"}'
- if $running_under_some_shell;
-my $startperl;
-my $perlpath;
-($startperl = <<'/../') =~ s/\s*\z//;
-#!/usr/bin/perl
-/../
-($perlpath = <<'/../') =~ s/\s*\z//;
-/usr/bin/perl
-/../
-
-$0 =~ s/^.*?(\w+)[\.\w]*$/$1/;
-
-# (p)sed - a stream editor
-# History: Aug 12 2000: Original version.
-# Mar 25 2002: Rearrange generated Perl program.
-# Jul 23 2007: Fix bug in regex stripping (M.Thorland)
-
-use strict;
-use integer;
-use Symbol;
-
-=head1 NAME
-
-psed - a stream editor
-
-=head1 SYNOPSIS
-
- psed [-an] script [file ...]
- psed [-an] [-e script] [-f script-file] [file ...]
-
- s2p [-an] [-e script] [-f script-file]
-
-=head1 DESCRIPTION
-
-A stream editor reads the input stream consisting of the specified files
-(or standard input, if none are given), processes is line by line by
-applying a script consisting of edit commands, and writes resulting lines
-to standard output. The filename `C<->' may be used to read standard input.
-
-The edit script is composed from arguments of B<-e> options and
-script-files, in the given order. A single script argument may be specified
-as the first parameter.
-
-If this program is invoked with the name F<s2p>, it will act as a
-sed-to-Perl translator. See L<"sed Script Translation">.
-
-B<sed> returns an exit code of 0 on success or >0 if an error occurred.
-
-=head1 OPTIONS
-
-=over 4
-
-=item B<-a>
-
-A file specified as argument to the B<w> edit command is by default
-opened before input processing starts. Using B<-a>, opening of such
-files is delayed until the first line is actually written to the file.
-
-=item B<-e> I<script>
-
-The editing commands defined by I<script> are appended to the script.
-Multiple commands must be separated by newlines.
-
-=item B<-f> I<script-file>
-
-Editing commands from the specified I<script-file> are read and appended
-to the script.
-
-=item B<-n>
-
-By default, a line is written to standard output after the editing script
-has been applied to it. The B<-n> option suppresses automatic printing.
-
-=back
-
-=head1 COMMANDS
-
-B<sed> command syntax is defined as
-
-Z<> Z<> Z<> Z<>[I<address>[B<,>I<address>]][B<!>]I<function>[I<argument>]
-
-with whitespace being permitted before or after addresses, and between
-the function character and the argument. The I<address>es and the
-address inverter (C<!>) are used to restrict the application of a
-command to the selected line(s) of input.
-
-Each command must be on a line of its own, except where noted in
-the synopses below.
-
-The edit cycle performed on each input line consist of reading the line
-(without its trailing newline character) into the I<pattern space>,
-applying the applicable commands of the edit script, writing the final
-contents of the pattern space and a newline to the standard output.
-A I<hold space> is provided for saving the contents of the
-pattern space for later use.
-
-=head2 Addresses
-
-A sed address is either a line number or a pattern, which may be combined
-arbitrarily to construct ranges. Lines are numbered across all input files.
-
-Any address may be followed by an exclamation mark (`C<!>'), selecting
-all lines not matching that address.
-
-=over 4
-
-=item I<number>
-
-The line with the given number is selected.
-
-=item B<$>
-
-A dollar sign (C<$>) is the line number of the last line of the input stream.
-
-=item B</>I<regular expression>B</>
-
-A pattern address is a basic regular expression (see
-L<"Basic Regular Expressions">), between the delimiting character C</>.
-Any other character except C<\> or newline may be used to delimit a
-pattern address when the initial delimiter is prefixed with a
-backslash (`C<\>').
-
-=back
-
-If no address is given, the command selects every line.
-
-If one address is given, it selects the line (or lines) matching the
-address.
-
-Two addresses select a range that begins whenever the first address
-matches, and ends (including that line) when the second address matches.
-If the first (second) address is a matching pattern, the second
-address is not applied to the very same line to determine the end of
-the range. Likewise, if the second address is a matching pattern, the
-first address is not applied to the very same line to determine the
-begin of another range. If both addresses are line numbers,
-and the second line number is less than the first line number, then
-only the first line is selected.
-
-
-=head2 Functions
-
-The maximum permitted number of addresses is indicated with each
-function synopsis below.
-
-The argument I<text> consists of one or more lines following the command.
-Embedded newlines in I<text> must be preceded with a backslash. Other
-backslashes in I<text> are deleted and the following character is taken
-literally.
-
-=over 4
-
-=cut
-
-my %ComTab;
-my %GenKey;
-#--------------------------------------------------------------------------
-$ComTab{'a'}=[ 1, 'txt', \&Emit, '{ push( @Q, <<'."'TheEnd' ) }\n" ]; #ok
-
-=item [1addr]B<a\> I<text>
-
-Write I<text> (which must start on the line following the command)
-to standard output immediately before reading the next line
-of input, either by executing the B<N> function or by beginning a new cycle.
-
-=cut
-
-#--------------------------------------------------------------------------
-$ComTab{'b'}=[ 2, 'str', \&Branch, '{ goto XXX; }' ]; #ok
-
-=item [2addr]B<b> [I<label>]
-
-Branch to the B<:> function with the specified I<label>. If no label
-is given, branch to the end of the script.
-
-=cut
-
-#--------------------------------------------------------------------------
-$ComTab{'c'}=[ 2, 'txt', \&Change, <<'-X-' ]; #ok
-{ print <<'TheEnd'; } $doPrint = 0; goto EOS;
--X-
-### continue OK => next CYCLE;
-
-=item [2addr]B<c\> I<text>
-
-The line, or range of lines, selected by the address is deleted.
-The I<text> (which must start on the line following the command)
-is written to standard output. With an address range, this occurs at
-the end of the range.
-
-=cut
-
-#--------------------------------------------------------------------------
-$ComTab{'d'}=[ 2, '', \&Emit, <<'-X-' ]; #ok
-{ $doPrint = 0;
- goto EOS;
-}
--X-
-### continue OK => next CYCLE;
-
-=item [2addr]B<d>
-
-Deletes the pattern space and starts the next cycle.
-
-=cut
-
-#--------------------------------------------------------------------------
-$ComTab{'D'}=[ 2, '', \&Emit, <<'-X-' ]; #ok
-{ s/^.*\n?//;
- if(length($_)){ goto BOS } else { goto EOS }
-}
--X-
-### continue OK => next CYCLE;
-
-=item [2addr]B<D>
-
-Deletes the pattern space through the first embedded newline or to the end.
-If the pattern space becomes empty, a new cycle is started, otherwise
-execution of the script is restarted.
-
-=cut
-
-#--------------------------------------------------------------------------
-$ComTab{'g'}=[ 2, '', \&Emit, '{ $_ = $Hold };' ]; #ok
-
-=item [2addr]B<g>
-
-Replace the contents of the pattern space with the hold space.
-
-=cut
-
-#--------------------------------------------------------------------------
-$ComTab{'G'}=[ 2, '', \&Emit, '{ $_ .= "\n"; $_ .= $Hold };' ]; #ok
-
-=item [2addr]B<G>
-
-Append a newline and the contents of the hold space to the pattern space.
-
-=cut
-
-#--------------------------------------------------------------------------
-$ComTab{'h'}=[ 2, '', \&Emit, '{ $Hold = $_ }' ]; #ok
-
-=item [2addr]B<h>
-
-Replace the contents of the hold space with the pattern space.
-
-=cut
-
-#--------------------------------------------------------------------------
-$ComTab{'H'}=[ 2, '', \&Emit, '{ $Hold .= "\n"; $Hold .= $_; }' ]; #ok
-
-=item [2addr]B<H>
-
-Append a newline and the contents of the pattern space to the hold space.
-
-=cut
-
-#--------------------------------------------------------------------------
-$ComTab{'i'}=[ 1, 'txt', \&Emit, '{ print <<'."'TheEnd' }\n" ]; #ok
-
-=item [1addr]B<i\> I<text>
-
-Write the I<text> (which must start on the line following the command)
-to standard output.
-
-=cut
-
-#--------------------------------------------------------------------------
-$ComTab{'l'}=[ 2, '', \&Emit, '{ _l() }' ]; #okUTF8
-
-=item [2addr]B<l>
-
-Print the contents of the pattern space: non-printable characters are
-shown in C-style escaped form; long lines are split and have a trailing
-`C<\>' at the point of the split; the true end of a line is marked with
-a `C<$>'. Escapes are: `\a', `\t', `\n', `\f', `\r', `\e' for
-BEL, HT, LF, FF, CR, ESC, respectively, and `\' followed by a three-digit
-octal number for all other non-printable characters.
-
-=cut
-
-#--------------------------------------------------------------------------
-$ComTab{'n'}=[ 2, '', \&Emit, <<'-X-' ]; #ok
-{ print $_, "\n" if $doPrint;
- printQ() if @Q;
- $CondReg = 0;
- last CYCLE unless getsARGV();
- chomp();
-}
--X-
-
-=item [2addr]B<n>
-
-If automatic printing is enabled, write the pattern space to the standard
-output. Replace the pattern space with the next line of input. If
-there is no more input, processing is terminated.
-
-=cut
-
-#--------------------------------------------------------------------------
-$ComTab{'N'}=[ 2, '', \&Emit, <<'-X-' ]; #ok
-{ printQ() if @Q;
- $CondReg = 0;
- last CYCLE unless getsARGV( $h );
- chomp( $h );
- $_ .= "\n$h";
-}
--X-
-
-=item [2addr]B<N>
-
-Append a newline and the next line of input to the pattern space. If
-there is no more input, processing is terminated.
-
-=cut
-
-#--------------------------------------------------------------------------
-$ComTab{'p'}=[ 2, '', \&Emit, '{ print $_, "\n"; }' ]; #ok
-
-=item [2addr]B<p>
-
-Print the pattern space to the standard output. (Use the B<-n> option
-to suppress automatic printing at the end of a cycle if you want to
-avoid double printing of lines.)
-
-=cut
-
-#--------------------------------------------------------------------------
-$ComTab{'P'}=[ 2, '', \&Emit, <<'-X-' ]; #ok
-{ if( /^(.*)/ ){ print $1, "\n"; } }
--X-
-
-=item [2addr]B<P>
-
-Prints the pattern space through the first embedded newline or to the end.
-
-=cut
-
-#--------------------------------------------------------------------------
-$ComTab{'q'}=[ 1, 'str', \&Emit, <<'-X-' ]; #ok
-{ print $_, "\n" if $doPrint;
- $exitstatus = '-X-';
- last CYCLE;
-}
--X-
-
-=item [1addr]B<q>
-
-Branch to the end of the script and quit without starting a new cycle.
-
-=cut
-
-#--------------------------------------------------------------------------
-$ComTab{'r'}=[ 1, 'str', \&Emit, "{ _r( '-X-' ) }" ]; #ok
-
-=item [1addr]B<r> I<file>
-
-Copy the contents of the I<file> to standard output immediately before
-the next attempt to read a line of input. Any error encountered while
-reading I<file> is silently ignored.
-
-=cut
-
-#--------------------------------------------------------------------------
-$ComTab{'s'}=[ 2, 'sub', \&Emit, '' ]; #ok
-
-=item [2addr]B<s/>I<regular expression>B</>I<replacement>B</>I<flags>
-
-Substitute the I<replacement> string for the first substring in
-the pattern space that matches the I<regular expression>.
-Any character other than backslash or newline can be used instead of a
-slash to delimit the regular expression and the replacement.
-To use the delimiter as a literal character within the regular expression
-and the replacement, precede the character by a backslash (`C<\>').
-
-Literal newlines may be embedded in the replacement string by
-preceding a newline with a backslash.
-
-Within the replacement, an ampersand (`C<&>') is replaced by the string
-matching the regular expression. The strings `C<\1>' through `C<\9>' are
-replaced by the corresponding subpattern (see L<"Basic Regular Expressions">).
-To get a literal `C<&>' or `C<\>' in the replacement text, precede it
-by a backslash.
-
-The following I<flags> modify the behaviour of the B<s> command:
-
-=over 8
-
-=item B<g>
-
-The replacement is performed for all matching, non-overlapping substrings
-of the pattern space.
-
-=item B<1>..B<9>
-
-Replace only the n-th matching substring of the pattern space.
-
-=item B<p>
-
-If the substitution was made, print the new value of the pattern space.
-
-=item B<w> I<file>
-
-If the substitution was made, write the new value of the pattern space
-to the specified file.
-
-=back
-
-=cut
-
-#--------------------------------------------------------------------------
-$ComTab{'t'}=[ 2, 'str', \&Branch, '{ goto XXX if _t() }' ]; #ok
-
-=item [2addr]B<t> [I<label>]
-
-Branch to the B<:> function with the specified I<label> if any B<s>
-substitutions have been made since the most recent reading of an input line
-or execution of a B<t> function. If no label is given, branch to the end of
-the script.
-
-
-=cut
-
-#--------------------------------------------------------------------------
-$ComTab{'w'}=[ 2, 'str', \&Write, "{ _w( '-X-' ) }" ]; #ok
-
-=item [2addr]B<w> I<file>
-
-The contents of the pattern space are written to the I<file>.
-
-=cut
-
-#--------------------------------------------------------------------------
-$ComTab{'x'}=[ 2, '', \&Emit, '{ ($Hold, $_) = ($_, $Hold) }' ]; #ok
-
-=item [2addr]B<x>
-
-Swap the contents of the pattern space and the hold space.
-
-=cut
-
-#--------------------------------------------------------------------------
-$ComTab{'y'}=[ 2, 'tra', \&Emit, '' ]; #ok
-=item [2addr]B<y>B</>I<string1>B</>I<string2>B</>
-
-In the pattern space, replace all characters occuring in I<string1> by the
-character at the corresponding position in I<string2>. It is possible
-to use any character (other than a backslash or newline) instead of a
-slash to delimit the strings. Within I<string1> and I<string2>, a
-backslash followed by any character other than a newline is that literal
-character, and a backslash followed by an `n' is replaced by a newline
-character.
-
-=cut
-
-#--------------------------------------------------------------------------
-$ComTab{'='}=[ 1, '', \&Emit, '{ print "$.\n" }' ]; #ok
-
-=item [1addr]B<=>
-
-Prints the current line number on the standard output.
-
-=cut
-
-#--------------------------------------------------------------------------
-$ComTab{':'}=[ 0, 'str', \&Label, '' ]; #ok
-
-=item [0addr]B<:> [I<label>]
-
-The command specifies the position of the I<label>. It has no other effect.
-
-=cut
-
-#--------------------------------------------------------------------------
-$ComTab{'{'}=[ 2, '', \&BeginBlock, '{' ]; #ok
-$ComTab{'}'}=[ 0, '', \&EndBlock, ';}' ]; #ok
-# ';' to avoid warning on empty {}-block
-
-=item [2addr]B<{> [I<command>]
-
-=item [0addr]B<}>
-
-These two commands begin and end a command list. The first command may
-be given on the same line as the opening B<{> command. The commands
-within the list are jointly selected by the address(es) given on the
-B<{> command (but may still have individual addresses).
-
-=cut
-
-#--------------------------------------------------------------------------
-$ComTab{'#'}=[ 0, 'str', \&Comment, '' ]; #ok
-
-=item [0addr]B<#> [I<comment>]
-
-The entire line is ignored (treated as a comment). If, however, the first
-two characters in the script are `C<#n>', automatic printing of output is
-suppressed, as if the B<-n> option were given on the command line.
-
-=back
-
-=cut
-
-use vars qw{ $isEOF $Hold %wFiles @Q $CondReg $doPrint };
-
-my $useDEBUG = exists( $ENV{PSEDDEBUG} );
-my $useEXTBRE = $ENV{PSEDEXTBRE} || '';
-$useEXTBRE =~ s/[^<>wWyB]//g; # gawk RE's handle these
-
-my $doAutoPrint = 1; # automatic printing of pattern space (-n => 0)
-my $doOpenWrite = 1; # open w command output files at start (-a => 0)
-my $svOpenWrite = 0; # save $doOpenWrite
-
-# lower case $0 below as a VMSism. The VMS build procedure creates the
-# s2p file traditionally in upper case on the disk. When VMS is in a
-# case preserved or case sensitive mode, $0 will be returned in the exact
-# case which will be on the disk, and that is not predictable at this time.
-
-my $doGenerate = lc($0) eq 's2p';
-
-# Collected and compiled script
-#
-my( @Commands, %Defined, @BlockStack, %Label, $labNum, $Code, $Func );
-$Code = '';
-
-##################
-# Compile Time
-#
-# Labels
-#
-# Error handling
-#
-sub Warn($;$){
- my( $msg, $loc ) = @_;
- $loc ||= '';
- $loc .= ': ' if length( $loc );
- warn( "$0: $loc$msg\n" );
-}
-
-$labNum = 0;
-sub newLabel(){
- return 'L_'.++$labNum;
-}
-
-# safeHere: create safe here delimiter and modify opcode and argument
-#
-sub safeHere($$){
- my( $codref, $argref ) = @_;
- my $eod = 'EOD000';
- while( $$argref =~ /^$eod$/m ){
- $eod++;
- }
- $$codref =~ s/TheEnd/$eod/e;
- $$argref .= "$eod\n";
-}
-
-# Emit: create address logic and emit command
-#
-sub Emit($$$$$$){
- my( $addr1, $addr2, $negated, $opcode, $arg, $fl ) = @_;
- my $cond = '';
- if( defined( $addr1 ) ){
- if( defined( $addr2 ) ){
- $addr1 .= $addr2 =~ /^\d+$/ ? "..$addr2" : "...$addr2";
- } else {
- $addr1 .= ' == $.' if $addr1 =~ /^\d+$/;
- }
- $cond = $negated ? "unless( $addr1 )\n" : "if( $addr1 )\n";
- }
-
- if( $opcode eq '' ){
- $Code .= "$cond$arg\n";
-
- } elsif( $opcode =~ s/-X-/$arg/e ){
- $Code .= "$cond$opcode\n";
-
- } elsif( $opcode =~ /TheEnd/ ){
- safeHere( \$opcode, \$arg );
- $Code .= "$cond$opcode$arg";
-
- } else {
- $Code .= "$cond$opcode\n";
- }
- 0;
-}
-
-# Write (w command, w flag): store pathname
-#
-sub Write($$$$$$){
- my( $addr1, $addr2, $negated, $opcode, $path, $fl ) = @_;
- $wFiles{$path} = '';
- Emit( $addr1, $addr2, $negated, $opcode, $path, $fl );
-}
-
-
-# Label (: command): label definition
-#
-sub Label($$$$$$){
- my( $addr1, $addr2, $negated, $opcode, $lab, $fl ) = @_;
- my $rc = 0;
- $lab =~ s/\s+//;
- if( length( $lab ) ){
- my $h;
- if( ! exists( $Label{$lab} ) ){
- $h = $Label{$lab}{name} = newLabel();
- } else {
- $h = $Label{$lab}{name};
- if( exists( $Label{$lab}{defined} ) ){
- my $dl = $Label{$lab}{defined};
- Warn( "duplicate label $lab (first defined at $dl)", $fl );
- $rc = 1;
- }
- }
- $Label{$lab}{defined} = $fl;
- $Code .= "$h:;\n";
- }
- $rc;
-}
-
-# BeginBlock ({ command): push block start
-#
-sub BeginBlock($$$$$$){
- my( $addr1, $addr2, $negated, $opcode, $arg, $fl ) = @_;
- push( @BlockStack, [ $fl, $addr1, $addr2, $negated ] );
- Emit( $addr1, $addr2, $negated, $opcode, $arg, $fl );
-}
-
-# EndBlock (} command): check proper nesting
-#
-sub EndBlock($$$$$$){
- my( $addr1, $addr2, $negated, $opcode, $arg, $fl ) = @_;
- my $rc;
- my $jcom = pop( @BlockStack );
- if( defined( $jcom ) ){
- $rc = Emit( $addr1, $addr2, $negated, $opcode, $arg, $fl );
- } else {
- Warn( "unexpected `}'", $fl );
- $rc = 1;
- }
- $rc;
-}
-
-# Branch (t, b commands): check or create label, substitute default
-#
-sub Branch($$$$$$){
- my( $addr1, $addr2, $negated, $opcode, $lab, $fl ) = @_;
- $lab =~ s/\s+//; # no spaces at end
- my $h;
- if( length( $lab ) ){
- if( ! exists( $Label{$lab} ) ){
- $h = $Label{$lab}{name} = newLabel();
- } else {
- $h = $Label{$lab}{name};
- }
- push( @{$Label{$lab}{used}}, $fl );
- } else {
- $h = 'EOS';
- }
- $opcode =~ s/XXX/$h/e;
- Emit( $addr1, $addr2, $negated, $opcode, '', $fl );
-}
-
-# Change (c command): is special due to range end watching
-#
-sub Change($$$$$$){
- my( $addr1, $addr2, $negated, $opcode, $arg, $fl ) = @_;
- my $kwd = $negated ? 'unless' : 'if';
- if( defined( $addr2 ) ){
- $addr1 .= $addr2 =~ /^\d+$/ ? "..$addr2" : "...$addr2";
- if( ! $negated ){
- $addr1 = '$icnt = ('.$addr1.')';
- $opcode = 'if( $icnt =~ /E0$/ )' . $opcode;
- }
- } else {
- $addr1 .= ' == $.' if $addr1 =~ /^\d+$/;
- }
- safeHere( \$opcode, \$arg );
- $Code .= "$kwd( $addr1 ){\n $opcode$arg}\n";
- 0;
-}
-
-
-# Comment (# command): A no-op. Who would've thought that!
-#
-sub Comment($$$$$$){
- my( $addr1, $addr2, $negated, $opcode, $arg, $fl ) = @_;
-### $Code .= "# $arg\n";
- 0;
-}
-
-# stripRegex from the current command. If we're in the first
-# part of s///, trailing spaces have to be kept as the initial
-# part of the replacement string.
-#
-sub stripRegex($$;$){
- my( $del, $sref, $sub ) = @_;
- my $regex = $del;
- print "stripRegex:$del:$$sref:\n" if $useDEBUG;
- while( $$sref =~ s{^(.*?)(\\*)\Q$del\E(\s*)}{}s ){
- my ($lead, $sl, $rest) = ($1, $2, $3);
- $regex .= $lead.$sl.$del;
- if( !($lead =~ /(?:^|[^\\])\[^?\]?[^]]*$/) && length( $sl ) % 2 == 0 ){
- if( $sub && (length( $rest ) > 0) ){
- $$sref = $rest . $$sref;
- }
- return $regex;
- }
- $regex .= $rest;
- }
- undef();
-}
-
-# stripTrans: take a <del> terminated string from y command
-# honoring and cleaning up of \-escaped <del>'s
-#
-sub stripTrans($$){
- my( $del, $sref ) = @_;
- my $t = '';
- print "stripTrans:$del:$$sref:\n" if $useDEBUG;
- while( $$sref =~ s{^(.*?)(\\*)\Q$del\E}{}s ){
- my $sl = $2;
- $t .= $1;
- if( length( $sl ) % 2 == 0 ){
- $t .= $sl;
- $t =~ s/\\\\/\\/g;
- return $t;
- }
- chop( $sl );
- $t .= $sl.$del.$3;
- }
- undef();
-}
-
-# makey - construct Perl y/// from sed y///
-#
-sub makey($$$){
- my( $fr, $to, $fl ) = @_;
- my $error = 0;
-
- # Ensure that any '-' is up front.
- # Diagnose duplicate contradicting mappings
- my %tr;
- for( my $i = 0; $i < length($fr); $i++ ){
- my $fc = substr($fr,$i,1);
- my $tc = substr($to,$i,1);
- if( exists( $tr{$fc} ) && $tr{$fc} ne $tc ){
- Warn( "ambiguous translation for character `$fc' in `y' command",
- $fl );
- $error++;
- }
- $tr{$fc} = $tc;
- }
- $fr = $to = '';
- if( exists( $tr{'-'} ) ){
- ( $fr, $to ) = ( '-', $tr{'-'} );
- delete( $tr{'-'} );
- } else {
- $fr = $to = '';
- }
- # might just as well sort it...
- for my $fc ( sort keys( %tr ) ){
- $fr .= $fc;
- $to .= $tr{$fc};
- }
- # make embedded delimiters and newlines safe
- $fr =~ s/([{}])/\$1/g;
- $to =~ s/([{}])/\$1/g;
- $fr =~ s/\n/\\n/g;
- $to =~ s/\n/\\n/g;
- return $error ? undef() : "{ y{$fr}{$to}; }";
-}
-
-######
-# makes - construct Perl s/// from sed s///
-#
-sub makes($$$$$$$){
- my( $regex, $subst, $path, $global, $print, $nmatch, $fl ) = @_;
-
- # make embedded newlines safe
- $regex =~ s/\n/\\n/g;
- $subst =~ s/\n/\\n/g;
-
- my $code;
- # n-th occurrence
- #
- if( length( $nmatch ) ){
- $code = <<TheEnd;
-{ \$n = $nmatch;
- while( --\$n && ( \$s = m ${regex}g ) ){}
- \$s = ( substr( \$_, pos() ) =~ s ${regex}${subst}s ) if \$s;
- \$CondReg ||= \$s;
-TheEnd
- } else {
- $code = <<TheEnd;
-{ \$s = s ${regex}${subst}s${global};
- \$CondReg ||= \$s;
-TheEnd
- }
- if( $print ){
- $code .= ' print $_, "\n" if $s;'."\n";
- }
- if( defined( $path ) ){
- $wFiles{$path} = '';
- $code .= " _w( '$path' ) if \$s;\n";
- $GenKey{'w'} = 1;
- }
- $code .= "}";
-}
-
-=head1 BASIC REGULAR EXPRESSIONS
-
-A I<Basic Regular Expression> (BRE), as defined in POSIX 1003.2, consists
-of I<atoms>, for matching parts of a string, and I<bounds>, specifying
-repetitions of a preceding atom.
-
-=head2 Atoms
-
-The possible atoms of a BRE are: B<.>, matching any single character;
-B<^> and B<$>, matching the null string at the beginning or end
-of a string, respectively; a I<bracket expressions>, enclosed
-in B<[> and B<]> (see below); and any single character with no
-other significance (matching that character). A B<\> before one
-of: B<.>, B<^>, B<$>, B<[>, B<*>, B<\>, matching the character
-after the backslash. A sequence of atoms enclosed in B<\(> and B<\)>
-becomes an atom and establishes the target for a I<backreference>,
-consisting of the substring that actually matches the enclosed atoms.
-Finally, B<\> followed by one of the digits B<0> through B<9> is a
-backreference.
-
-A B<^> that is not first, or a B<$> that is not last does not have
-a special significance and need not be preceded by a backslash to
-become literal. The same is true for a B<]>, that does not terminate
-a bracket expression.
-
-An unescaped backslash cannot be last in a BRE.
-
-=head2 Bounds
-
-The BRE bounds are: B<*>, specifying 0 or more matches of the preceding
-atom; B<\{>I<count>B<\}>, specifying that many repetitions;
-B<\{>I<minimum>B<,\}>, giving a lower limit; and
-B<\{>I<minimum>B<,>I<maximum>B<\}> finally defines a lower and upper
-bound.
-
-A bound appearing as the first item in a BRE is taken literally.
-
-=head2 Bracket Expressions
-
-A I<bracket expression> is a list of characters, character ranges
-and character classes enclosed in B<[> and B<]> and matches any
-single character from the represented set of characters.
-
-A character range is written as two characters separated by B<-> and
-represents all characters (according to the character collating sequence)
-that are not less than the first and not greater than the second.
-(Ranges are very collating-sequence-dependent, and portable programs
-should avoid relying on them.)
-
-A character class is one of the class names
-
- alnum digit punct
- alpha graph space
- blank lower upper
- cntrl print xdigit
-
-enclosed in B<[:> and B<:]> and represents the set of characters
-as defined in ctype(3).
-
-If the first character after B<[> is B<^>, the sense of matching is
-inverted.
-
-To include a literal `C<^>', place it anywhere else but first. To
-include a literal 'C<]>' place it first or immediately after an
-initial B<^>. To include a literal `C<->' make it the first (or
-second after B<^>) or last character, or the second endpoint of
-a range.
-
-The special bracket expression constructs C<[[:E<lt>:]]> and C<[[:E<gt>:]]>
-match the null string at the beginning and end of a word respectively.
-(Note that neither is identical to Perl's `\b' atom.)
-
-=head2 Additional Atoms
-
-Since some sed implementations provide additional regular expression
-atoms (not defined in POSIX 1003.2), B<psed> is capable of translating
-the following backslash escapes:
-
-=over 4
-
-=item B<\E<lt>> This is the same as C<[[:E<gt>:]]>.
-
-=item B<\E<gt>> This is the same as C<[[:E<lt>:]]>.
-
-=item B<\w> This is an abbreviation for C<[[:alnum:]_]>.
-
-=item B<\W> This is an abbreviation for C<[^[:alnum:]_]>.
-
-=item B<\y> Match the empty string at a word boundary.
-
-=item B<\B> Match the empty string between any two either word or non-word characters.
-
-=back
-
-To enable this feature, the environment variable PSEDEXTBRE must be set
-to a string containing the requested characters, e.g.:
-C<PSEDEXTBRE='E<lt>E<gt>wW'>.
-
-=cut
-
-#####
-# bre2p - convert BRE to Perl RE
-#
-sub peek(\$$){
- my( $pref, $ic ) = @_;
- $ic < length($$pref)-1 ? substr( $$pref, $ic+1, 1 ) : '';
-}
-
-sub bre2p($$$){
- my( $del, $pat, $fl ) = @_;
- my $led = $del;
- $led =~ tr/{([</})]>/;
- $led = '' if $led eq $del;
-
- $pat = substr( $pat, 1, length($pat) - 2 );
- my $res = '';
- my $bracklev = 0;
- my $backref = 0;
- my $parlev = 0;
- for( my $ic = 0; $ic < length( $pat ); $ic++ ){
- my $c = substr( $pat, $ic, 1 );
- if( $c eq '\\' ){
- ### backslash escapes
- my $nc = peek($pat,$ic);
- if( $nc eq '' ){
- Warn( "`\\' cannot be last in pattern", $fl );
- return undef();
- }
- $ic++;
- if( $nc eq $del ){ ## \<pattern del> => \<pattern del>
- $res .= "\\$del";
-
- } elsif( $nc =~ /([[.*\\n])/ ){
- ## check for \-escaped magics and \n:
- ## \[ \. \* \\ \n stay as they are
- $res .= '\\'.$nc;
-
- } elsif( $nc eq '(' ){ ## \( => (
- $parlev++;
- $res .= '(';
-
- } elsif( $nc eq ')' ){ ## \) => )
- $parlev--;
- $backref++;
- if( $parlev < 0 ){
- Warn( "unmatched `\\)'", $fl );
- return undef();
- }
- $res .= ')';
-
- } elsif( $nc eq '{' ){ ## repetition factor \{<i>[,[<j>]]\}
- my $endpos = index( $pat, '\\}', $ic );
- if( $endpos < 0 ){
- Warn( "unmatched `\\{'", $fl );
- return undef();
- }
- my $rep = substr( $pat, $ic+1, $endpos-($ic+1) );
- $ic = $endpos + 1;
-
- if( $res =~ /^\^?$/ ){
- $res .= "\\{$rep\}";
- } elsif( $rep =~ /^(\d+)(,?)(\d*)?$/ ){
- my $min = $1;
- my $com = $2 || '';
- my $max = $3;
- if( length( $max ) ){
- if( $max < $min ){
- Warn( "maximum less than minimum in `\\{$rep\\}'",
- $fl );
- return undef();
- }
- } else {
- $max = '';
- }
- # simplify some
- if( $min == 0 && $max eq '1' ){
- $res .= '?';
- } elsif( $min == 1 && "$com$max" eq ',' ){
- $res .= '+';
- } elsif( $min == 0 && "$com$max" eq ',' ){
- $res .= '*';
- } else {
- $res .= "{$min$com$max}";
- }
- } else {
- Warn( "invalid repeat clause `\\{$rep\\}'", $fl );
- return undef();
- }
-
- } elsif( $nc =~ /^[1-9]$/ ){
- ## \1 .. \9 => \1 .. \9, but check for a following digit
- if( $nc > $backref ){
- Warn( "invalid backreference ($nc)", $fl );
- return undef();
- }
- $res .= "\\$nc";
- if( peek($pat,$ic) =~ /[0-9]/ ){
- $res .= '(?:)';
- }
-
- } elsif( $useEXTBRE && ( $nc =~ /[$useEXTBRE]/ ) ){
- ## extensions - at most <>wWyB - not in POSIX
- if( $nc eq '<' ){ ## \< => \b(?=\w), be precise
- $res .= '\\b(?<=\\W)';
- } elsif( $nc eq '>' ){ ## \> => \b(?=\W), be precise
- $res .= '\\b(?=\\W)';
- } elsif( $nc eq 'y' ){ ## \y => \b
- $res .= '\\b';
- } else { ## \B, \w, \W remain the same
- $res .= "\\$nc";
- }
- } elsif( $nc eq $led ){
- ## \<closing bracketing-delimiter> - keep '\'
- $res .= "\\$nc";
-
- } else { ## \ <char> => <char> ("as if `\' were not present")
- $res .= $nc;
- }
-
- } elsif( $c eq '.' ){ ## . => .
- $res .= $c;
-
- } elsif( $c eq '*' ){ ## * => * but \* if there's nothing preceding it
- if( $res =~ /^\^?$/ ){
- $res .= '\\*';
- } elsif( substr( $res, -1, 1 ) ne '*' ){
- $res .= $c;
- }
-
- } elsif( $c eq '[' ){
- ## parse []: [^...] [^]...] [-...]
- my $add = '[';
- if( peek($pat,$ic) eq '^' ){
- $ic++;
- $add .= '^';
- }
- my $nc = peek($pat,$ic);
- if( $nc eq ']' || $nc eq '-' ){
- $add .= $nc;
- $ic++;
- }
- # check that [ is not trailing
- if( $ic >= length( $pat ) - 1 ){
- Warn( "unmatched `['", $fl );
- return undef();
- }
- # look for [:...:] and x-y
- my $rstr = substr( $pat, $ic+1 );
- if( $rstr =~ /^((?:\[:\(\w+|[><]\):\]|[^]-](?:-[^]])?)*)/ ){
- my $cnt = $1;
- $ic += length( $cnt );
- $cnt =~ s/([\/\$])/\\$1/g; # `/', `$' are magic in Perl []
- # try some simplifications
- my $red = $cnt;
- if( $red =~ s/0-9// ){
- $cnt = $red.'\d';
- if( $red =~ s/A-Z// && $red =~ s/a-z// && $red =~ s/_// ){
- $cnt = $red.'\w';
- }
- }
- $add .= $cnt;
-
- # POSIX 1003.2 has this (optional) for begin/end word
- $add = '\\b(?=\\W)' if $add eq '[[:<:]]';
- $add = '\\b(?<=\\W)' if $add eq '[[:>:]]';
-
- }
-
- ## may have a trailing `-' before `]'
- if( $ic < length($pat) - 1 &&
- substr( $pat, $ic+1 ) =~ /^(-?])/ ){
- $ic += length( $1 );
- $add .= $1;
- # another simplification
- $add =~ s/^\[(\^?)(\\[dw])]$/ $1 eq '^' ? uc($2) : $2 /e;
- $res .= $add;
- } else {
- Warn( "unmatched `['", $fl );
- return undef();
- }
-
- } elsif( $c eq $led ){ ## unescaped <closing bracketing-delimiter>
- $res .= "\\$c";
-
- } elsif( $c eq ']' ){ ## unmatched ] is not magic
- $res .= ']';
-
- } elsif( $c =~ /[|+?{}()@#\/]/ ){ ## not magic in BRE, but in Perl: \-quote
- $res .= "\\$c";
-
- } elsif( $c eq '^' ){ ## not magic unless 1st, but in Perl: \-quote
- $res .= length( $res ) ? '\\^' : '^';
-
- } elsif( $c eq '$' ){ ## not magic unless last, but in Perl: \-quote
- $res .= $ic == length( $pat ) - 1 ? '$' : '\\$';
-
- } else {
- $res .= $c;
- }
- }
-
- if( $parlev ){
- Warn( "unmatched `\\('", $fl );
- return undef();
- }
-
- # final cleanup: eliminate raw HTs
- $res =~ s/\t/\\t/g;
- return $del . $res . ( $led ? $led : $del );
-}
-
-
-#####
-# sub2p - convert sed substitution to Perl substitution
-#
-sub sub2p($$$){
- my( $del, $subst, $fl ) = @_;
- my $led = $del;
- $led =~ tr/{([</})]>/;
- $led = '' if $led eq $del;
-
- $subst = substr( $subst, 1, length($subst) - 2 );
- my $res = '';
-
- for( my $ic = 0; $ic < length( $subst ); $ic++ ){
- my $c = substr( $subst, $ic, 1 );
- if( $c eq '\\' ){
- ### backslash escapes
- my $nc = peek($subst,$ic);
- if( $nc eq '' ){
- Warn( "`\\' cannot be last in substitution", $fl );
- return undef();
- }
- $ic++;
- if( $nc =~ /[\\$del$led]/ ){ ## \ and delimiter
- $res .= '\\' . $nc;
- } elsif( $nc =~ /[1-9]/ ){ ## \1 - \9 => ${1} - ${9}
- $res .= '${' . $nc . '}';
- } else { ## everything else (includes &): omit \
- $res .= $nc;
- }
- } elsif( $c eq '&' ){ ## & => $&
- $res .= '$&';
- } elsif( $c =~ /[\$\@$led]/ ){ ## magic in Perl's substitution string
- $res .= '\\' . $c;
- } else {
- $res .= $c;
- }
- }
-
- # final cleanup: eliminate raw HTs
- $res =~ s/\t/\\t/g;
- return ( $led ? $del : $led ) . $res . ( $led ? $led : $del );
-}
-
-
-sub Parse(){
- my $error = 0;
- my( $pdef, $pfil, $plin );
- for( my $icom = 0; $icom < @Commands; $icom++ ){
- my $cmd = $Commands[$icom];
- print "Parse:$cmd:\n" if $useDEBUG;
- $cmd =~ s/^\s+//;
- next unless length( $cmd );
- my $scom = $icom;
- if( exists( $Defined{$icom} ) ){
- $pdef = $Defined{$icom};
- if( $pdef =~ /^ #(\d+)/ ){
- $pfil = 'expression #';
- $plin = $1;
- } else {
- $pfil = "$pdef l.";
- $plin = 1;
- }
- } else {
- $plin++;
- }
- my $fl = "$pfil$plin";
-
- # insert command as comment in gnerated code
- #
- $Code .= "# $cmd\n" if $doGenerate;
-
- # The Address(es)
- #
- my( $negated, $naddr, $addr1, $addr2 );
- $naddr = 0;
- if( $cmd =~ s/^(\d+)\s*// ){
- $addr1 = "$1"; $naddr++;
- } elsif( $cmd =~ s/^\$\s*// ){
- $addr1 = 'eofARGV()'; $naddr++;
- } elsif( $cmd =~ s{^(/)}{} || $cmd =~ s{^\\(.)}{} ){
- my $del = $1;
- my $regex = stripRegex( $del, \$cmd );
- if( defined( $regex ) ){
- $addr1 = 'm '.bre2p( $del, $regex, $fl ).'s';
- $naddr++;
- } else {
- Warn( "malformed regex, 1st address", $fl );
- $error++;
- next;
- }
- }
- if( defined( $addr1 ) && $cmd =~ s/,\s*// ){
- if( $cmd =~ s/^(\d+)\s*// ){
- $addr2 = "$1"; $naddr++;
- } elsif( $cmd =~ s/^\$\s*// ){
- $addr2 = 'eofARGV()'; $naddr++;
- } elsif( $cmd =~ s{^(/)}{} || $cmd =~ s{^\\(.)}{} ){
- my $del = $1;
- my $regex = stripRegex( $del, \$cmd );
- if( defined( $regex ) ){
- $addr2 = 'm '. bre2p( $del, $regex, $fl ).'s';
- $naddr++;
- } else {
- Warn( "malformed regex, 2nd address", $fl );
- $error++;
- next;
- }
- } else {
- Warn( "invalid address after `,'", $fl );
- $error++;
- next;
- }
- }
-
- # address modifier `!'
- #
- $negated = $cmd =~ s/^!\s*//;
- if( defined( $addr1 ) ){
- print "Parse: addr1=$addr1" if $useDEBUG;
- if( defined( $addr2 ) ){
- print ", addr2=$addr2 " if $useDEBUG;
- # both numeric and addr1 > addr2 => eliminate addr2
- undef( $addr2 ) if $addr1 =~ /^\d+$/ &&
- $addr2 =~ /^\d+$/ && $addr1 > $addr2;
- }
- }
- print 'negated' if $useDEBUG && $negated;
- print " command:$cmd\n" if $useDEBUG;
-
- # The Command
- #
- if( $cmd !~ s/^([:#={}abcdDgGhHilnNpPqrstwxy])\s*// ){
- my $h = substr( $cmd, 0, 1 );
- Warn( "unknown command `$h'", $fl );
- $error++;
- next;
- }
- my $key = $1;
-
- my $tabref = $ComTab{$key};
- $GenKey{$key} = 1;
- if( $naddr > $tabref->[0] ){
- Warn( "excess address(es)", $fl );
- $error++;
- next;
- }
-
- my $arg = '';
- if( $tabref->[1] eq 'str' ){
- # take remainder - don't care if it is empty
- $arg = $cmd;
- $cmd = '';
-
- } elsif( $tabref->[1] eq 'txt' ){
- # multi-line text
- my $goon = $cmd =~ /(.*)\\$/;
- if( length( $1 ) ){
- Warn( "extra characters after command ($cmd)", $fl );
- $error++;
- }
- while( $goon ){
- $icom++;
- if( $icom > $#Commands ){
- Warn( "unexpected end of script", $fl );
- $error++;
- last;
- }
- $cmd = $Commands[$icom];
- $Code .= "# $cmd\n" if $doGenerate;
- $goon = $cmd =~ s/\\$//;
- $cmd =~ s/\\(.)/$1/g;
- $arg .= "\n" if length( $arg );
- $arg .= $cmd;
- }
- $arg .= "\n" if length( $arg );
- $cmd = '';
-
- } elsif( $tabref->[1] eq 'sub' ){
- # s///
- if( ! length( $cmd ) ){
- Warn( "`s' command requires argument", $fl );
- $error++;
- next;
- }
- if( $cmd =~ s{^([^\\\n])}{} ){
- my $del = $1;
- my $regex = stripRegex( $del, \$cmd, "s" );
- if( ! defined( $regex ) ){
- Warn( "malformed regular expression", $fl );
- $error++;
- next;
- }
- $regex = bre2p( $del, $regex, $fl );
-
- # a trailing \ indicates embedded NL (in replacement string)
- while( $cmd =~ s/(?<!\\)\\$/\n/ ){
- $icom++;
- if( $icom > $#Commands ){
- Warn( "unexpected end of script", $fl );
- $error++;
- last;
- }
- $cmd .= $Commands[$icom];
- $Code .= "# $Commands[$icom]\n" if $doGenerate;
- }
-
- my $subst = stripRegex( $del, \$cmd );
- if( ! defined( $regex ) ){
- Warn( "malformed substitution expression", $fl );
- $error++;
- next;
- }
- $subst = sub2p( $del, $subst, $fl );
-
- # parse s/// modifier: g|p|0-9|w <file>
- my( $global, $nmatch, $print, $write ) =
- ( '', '', 0, undef );
- while( $cmd =~ s/^([gp0-9])// ){
- $1 eq 'g' ? ( $global = 'g' ) :
- $1 eq 'p' ? ( $print = $1 ) : ( $nmatch .= $1 );
- }
- $write = $1 if $cmd =~ s/w\s*(.*)$//;
- ### $nmatch =~ s/^(\d)\1*$/$1/; ### may be dangerous?
- if( $global && length( $nmatch ) || length( $nmatch ) > 1 ){
- Warn( "conflicting flags `$global$nmatch'", $fl );
- $error++;
- next;
- }
-
- $arg = makes( $regex, $subst,
- $write, $global, $print, $nmatch, $fl );
- if( ! defined( $arg ) ){
- $error++;
- next;
- }
-
- } else {
- Warn( "improper delimiter in s command", $fl );
- $error++;
- next;
- }
-
- } elsif( $tabref->[1] eq 'tra' ){
- # y///
- # a trailing \ indicates embedded newline
- while( $cmd =~ s/(?<!\\)\\$/\n/ ){
- $icom++;
- if( $icom > $#Commands ){
- Warn( "unexpected end of script", $fl );
- $error++;
- last;
- }
- $cmd .= $Commands[$icom];
- $Code .= "# $Commands[$icom]\n" if $doGenerate;
- }
- if( ! length( $cmd ) ){
- Warn( "`y' command requires argument", $fl );
- $error++;
- next;
- }
- my $d = substr( $cmd, 0, 1 ); $cmd = substr( $cmd, 1 );
- if( $d eq '\\' ){
- Warn( "`\\' not valid as delimiter in `y' command", $fl );
- $error++;
- next;
- }
- my $fr = stripTrans( $d, \$cmd );
- if( ! defined( $fr ) || ! length( $cmd ) ){
- Warn( "malformed `y' command argument", $fl );
- $error++;
- next;
- }
- my $to = stripTrans( $d, \$cmd );
- if( ! defined( $to ) ){
- Warn( "malformed `y' command argument", $fl );
- $error++;
- next;
- }
- if( length($fr) != length($to) ){
- Warn( "string lengths in `y' command differ", $fl );
- $error++;
- next;
- }
- if( ! defined( $arg = makey( $fr, $to, $fl ) ) ){
- $error++;
- next;
- }
-
- }
-
- # $cmd must be now empty - exception is {
- if( $cmd !~ /^\s*$/ ){
- if( $key eq '{' ){
- # dirty hack to process command on '{' line
- $Commands[$icom--] = $cmd;
- } else {
- Warn( "extra characters after command ($cmd)", $fl );
- $error++;
- next;
- }
- }
-
- # Make Code
- #
- if( &{$tabref->[2]}( $addr1, $addr2, $negated,
- $tabref->[3], $arg, $fl ) ){
- $error++;
- }
- }
-
- while( @BlockStack ){
- my $bl = pop( @BlockStack );
- Warn( "start of unterminated `{'", $bl );
- $error++;
- }
-
- for my $lab ( keys( %Label ) ){
- if( ! exists( $Label{$lab}{defined} ) ){
- for my $used ( @{$Label{$lab}{used}} ){
- Warn( "undefined label `$lab'", $used );
- $error++;
- }
- }
- }
-
- exit( 1 ) if $error;
-}
-
-
-##############
-#### MAIN ####
-##############
-
-sub usage(){
- print STDERR "Usage: sed [-an] command [file...]\n";
- print STDERR " [-an] [-e command] [-f script-file] [file...]\n";
-}
-
-###################
-# Here we go again...
-#
-my $expr = 0;
-while( @ARGV && $ARGV[0] =~ /^-(.)(.*)$/ ){
- my $opt = $1;
- my $arg = $2;
- shift( @ARGV );
- if( $opt eq 'e' ){
- if( length( $arg ) ){
- push( @Commands, split( "\n", $arg ) );
- } elsif( @ARGV ){
- push( @Commands, shift( @ARGV ) );
- } else {
- Warn( "option -e requires an argument" );
- usage();
- exit( 1 );
- }
- $expr++;
- $Defined{$#Commands} = " #$expr";
- next;
- }
- if( $opt eq 'f' ){
- my $path;
- if( length( $arg ) ){
- $path = $arg;
- } elsif( @ARGV ){
- $path = shift( @ARGV );
- } else {
- Warn( "option -f requires an argument" );
- usage();
- exit( 1 );
- }
- my $fst = $#Commands + 1;
- open( SCRIPT, "<$path" ) || die( "$0: $path: could not open ($!)\n" );
- my $cmd;
- while( defined( $cmd = <SCRIPT> ) ){
- chomp( $cmd );
- push( @Commands, $cmd );
- }
- close( SCRIPT );
- if( $#Commands >= $fst ){
- $Defined{$fst} = "$path";
- }
- next;
- }
- if( $opt eq '-' && $arg eq '' ){
- last;
- }
- if( $opt eq 'h' || $opt eq '?' ){
- usage();
- exit( 0 );
- }
- if( $opt eq 'n' ){
- $doAutoPrint = 0;
- } elsif( $opt eq 'a' ){
- $doOpenWrite = 0;
- } else {
- Warn( "illegal option `$opt'" );
- usage();
- exit( 1 );
- }
- if( length( $arg ) ){
- unshift( @ARGV, "-$arg" );
- }
-}
-
-# A singleton command may be the 1st argument when there are no options.
-#
-if( @Commands == 0 ){
- if( @ARGV == 0 ){
- Warn( "no script command given" );
- usage();
- exit( 1 );
- }
- push( @Commands, split( "\n", shift( @ARGV ) ) );
- $Defined{0} = ' #1';
-}
-
-print STDERR "Files: @ARGV\n" if $useDEBUG;
-
-# generate leading code
-#
-$Func = <<'[TheEnd]';
-
-# openARGV: open 1st input file
-#
-sub openARGV(){
- unshift( @ARGV, '-' ) unless @ARGV;
- my $file = shift( @ARGV );
- open( ARG, "<$file" )
- || die( "$0: can't open $file for reading ($!)\n" );
- $isEOF = 0;
-}
-
-# getsARGV: Read another input line into argument (default: $_).
-# Move on to next input file, and reset EOF flag $isEOF.
-sub getsARGV(;\$){
- my $argref = @_ ? shift() : \$_;
- while( $isEOF || ! defined( $$argref = <ARG> ) ){
- close( ARG );
- return 0 unless @ARGV;
- my $file = shift( @ARGV );
- open( ARG, "<$file" )
- || die( "$0: can't open $file for reading ($!)\n" );
- $isEOF = 0;
- }
- 1;
-}
-
-# eofARGV: end-of-file test
-#
-sub eofARGV(){
- return @ARGV == 0 && ( $isEOF = eof( ARG ) );
-}
-
-# makeHandle: Generates another file handle for some file (given by its path)
-# to be written due to a w command or an s command's w flag.
-sub makeHandle($){
- my( $path ) = @_;
- my $handle;
- if( ! exists( $wFiles{$path} ) || $wFiles{$path} eq '' ){
- $handle = $wFiles{$path} = gensym();
- if( $doOpenWrite ){
- if( ! open( $handle, ">$path" ) ){
- die( "$0: can't open $path for writing: ($!)\n" );
- }
- }
- } else {
- $handle = $wFiles{$path};
- }
- return $handle;
-}
-
-# printQ: Print queued output which is either a string or a reference
-# to a pathname.
-sub printQ(){
- for my $q ( @Q ){
- if( ref( $q ) ){
- # flush open w files so that reading this file gets it all
- if( exists( $wFiles{$$q} ) && $wFiles{$$q} ne '' ){
- open( $wFiles{$$q}, ">>$$q" );
- }
- # copy file to stdout: slow, but safe
- if( open( RF, "<$$q" ) ){
- while( defined( my $line = <RF> ) ){
- print $line;
- }
- close( RF );
- }
- } else {
- print $q;
- }
- }
- undef( @Q );
-}
-
-[TheEnd]
-
-# generate the sed loop
-#
-$Code .= <<'[TheEnd]';
-sub openARGV();
-sub getsARGV(;\$);
-sub eofARGV();
-sub printQ();
-
-# Run: the sed loop reading input and applying the script
-#
-sub Run(){
- my( $h, $icnt, $s, $n );
- # hack (not unbreakable :-/) to avoid // matching an empty string
- my $z = "\000"; $z =~ /$z/;
- my $exitstatus = 0;
- # Initialize.
- openARGV();
- $Hold = '';
- $CondReg = 0;
- $doPrint = $doAutoPrint;
-CYCLE:
- while( getsARGV() ){
- chomp();
- $CondReg = 0; # cleared on t
-BOS:;
-[TheEnd]
-
- # parse - avoid opening files when doing s2p
- #
- ( $svOpenWrite, $doOpenWrite ) = ( $doOpenWrite, $svOpenWrite )
- if $doGenerate;
- Parse();
- ( $svOpenWrite, $doOpenWrite ) = ( $doOpenWrite, $svOpenWrite )
- if $doGenerate;
-
- # append trailing code
- #
- $Code .= <<'[TheEnd]';
-EOS: if( $doPrint ){
- print $_, "\n";
- } else {
- $doPrint = $doAutoPrint;
- }
- printQ() if @Q;
- }
-
- exit( $exitstatus );
-}
-[TheEnd]
-
-
-# append optional functions, prepend prototypes
-#
-my $Proto = "# prototypes\n";
-if( $GenKey{'l'} ){
- $Proto .= "sub _l();\n";
- $Func .= <<'[TheEnd]';
-# _l: l command processing
-#
-sub _l(){
- my $h = $_;
- my $mcpl = 70;
- # transform non printing chars into escape notation
- $h =~ s/\\/\\\\/g;
- if( $h =~ /[^[:print:]]/ ){
- $h =~ s/\a/\\a/g;
- $h =~ s/\f/\\f/g;
- $h =~ s/\n/\\n/g;
- $h =~ s/\t/\\t/g;
- $h =~ s/\r/\\r/g;
- $h =~ s/\e/\\e/g;
- $h =~ s/([^[:print:]])/sprintf("\\%03o", ord($1))/ge;
- }
- # split into lines of length $mcpl
- while( length( $h ) > $mcpl ){
- my $l = substr( $h, 0, $mcpl-1 );
- $h = substr( $h, $mcpl );
- # remove incomplete \-escape from end of line
- if( $l =~ s/(?<!\\)(\\[0-7]{0,2})$// ){
- $h = $1 . $h;
- }
- print $l, "\\\n";
- }
- print "$h\$\n";
-}
-
-[TheEnd]
-}
-
-if( $GenKey{'r'} ){
- $Proto .= "sub _r(\$);\n";
- $Func .= <<'[TheEnd]';
-# _r: r command processing: Save a reference to the pathname.
-#
-sub _r($){
- my $path = shift();
- push( @Q, \$path );
-}
-
-[TheEnd]
-}
-
-if( $GenKey{'t'} ){
- $Proto .= "sub _t();\n";
- $Func .= <<'[TheEnd]';
-# _t: t command - condition register test/reset
-#
-sub _t(){
- my $res = $CondReg;
- $CondReg = 0;
- $res;
-}
-
-[TheEnd]
-}
-
-if( $GenKey{'w'} ){
- $Proto .= "sub _w(\$);\n";
- $Func .= <<'[TheEnd]';
-# _w: w command and s command's w flag - write to file
-#
-sub _w($){
- my $path = shift();
- my $handle = $wFiles{$path};
- if( ! $doOpenWrite && ! defined( fileno( $handle ) ) ){
- open( $handle, ">$path" )
- || die( "$0: $path: cannot open ($!)\n" );
- }
- print $handle $_, "\n";
-}
-
-[TheEnd]
-}
-
-$Code = $Proto . $Code;
-
-# magic "#n" - same as -n option
-#
-$doAutoPrint = 0 if substr( $Commands[0], 0, 2 ) eq '#n';
-
-# eval code - check for errors
-#
-print "Code:\n$Code$Func" if $useDEBUG;
-eval $Code . $Func;
-if( $@ ){
- print "Code:\n$Code$Func";
- die( "$0: internal error - generated incorrect Perl code: $@\n" );
-}
-
-if( $doGenerate ){
-
- # write full Perl program
- #
-
- # bang line, declarations, prototypes
- print <<TheEnd;
-#!$perlpath -w
-eval 'exec $perlpath -S \$0 \${1+"\$@"}'
- if 0;
-\$0 =~ s/^.*?(\\w+)\[\\.\\w+\]*\$/\$1/;
-
-use strict;
-use Symbol;
-use vars qw{ \$isEOF \$Hold \%wFiles \@Q \$CondReg
- \$doAutoPrint \$doOpenWrite \$doPrint };
-\$doAutoPrint = $doAutoPrint;
-\$doOpenWrite = $doOpenWrite;
-TheEnd
-
- my $wf = "'" . join( "', '", keys( %wFiles ) ) . "'";
- if( $wf ne "''" ){
- print <<TheEnd;
-sub makeHandle(\$);
-for my \$p ( $wf ){
- exit( 1 ) unless makeHandle( \$p );
-}
-TheEnd
- }
-
- print $Code;
- print "Run();\n";
- print $Func;
- exit( 0 );
-
-} else {
-
- # execute: make handles (and optionally open) all w files; run!
- for my $p ( keys( %wFiles ) ){
- exit( 1 ) unless makeHandle( $p );
- }
- Run();
-}
-
-
-=head1 ENVIRONMENT
-
-The environment variable C<PSEDEXTBRE> may be set to extend BREs.
-See L<"Additional Atoms">.
-
-=head1 DIAGNOSTICS
-
-=over 4
-
-=item ambiguous translation for character `%s' in `y' command
-
-The indicated character appears twice, with different translations.
-
-=item `[' cannot be last in pattern
-
-A `[' in a BRE indicates the beginning of a I<bracket expression>.
-
-=item `\' cannot be last in pattern
-
-A `\' in a BRE is used to make the subsequent character literal.
-
-=item `\' cannot be last in substitution
-
-A `\' in a subsitution string is used to make the subsequent character literal.
-
-=item conflicting flags `%s'
-
-In an B<s> command, either the `g' flag and an n-th occurrence flag, or
-multiple n-th occurrence flags are specified. Note that only the digits
-`1' through `9' are permitted.
-
-=item duplicate label %s (first defined at %s)
-
-=item excess address(es)
-
-The command has more than the permitted number of addresses.
-
-=item extra characters after command (%s)
-
-=item illegal option `%s'
-
-=item improper delimiter in s command
-
-The BRE and substitution may not be delimited with `\' or newline.
-
-=item invalid address after `,'
-
-=item invalid backreference (%s)
-
-The specified backreference number exceeds the number of backreferences
-in the BRE.
-
-=item invalid repeat clause `\{%s\}'
-
-The repeat clause does not contain a valid integer value, or pair of
-values.
-
-=item malformed regex, 1st address
-
-=item malformed regex, 2nd address
-
-=item malformed regular expression
-
-=item malformed substitution expression
-
-=item malformed `y' command argument
-
-The first or second string of a B<y> command is syntactically incorrect.
-
-=item maximum less than minimum in `\{%s\}'
-
-=item no script command given
-
-There must be at least one B<-e> or one B<-f> option specifying a
-script or script file.
-
-=item `\' not valid as delimiter in `y' command
-
-=item option -e requires an argument
-
-=item option -f requires an argument
-
-=item `s' command requires argument
-
-=item start of unterminated `{'
-
-=item string lengths in `y' command differ
-
-The translation table strings in a B<y> command must have equal lengths.
-
-=item undefined label `%s'
-
-=item unexpected `}'
-
-A B<}> command without a preceding B<{> command was encountered.
-
-=item unexpected end of script
-
-The end of the script was reached although a text line after a
-B<a>, B<c> or B<i> command indicated another line.
-
-=item unknown command `%s'
-
-=item unterminated `['
-
-A BRE contains an unterminated bracket expression.
-
-=item unterminated `\('
-
-A BRE contains an unterminated backreference.
-
-=item `\{' without closing `\}'
-
-A BRE contains an unterminated bounds specification.
-
-=item `\)' without preceding `\('
-
-=item `y' command requires argument
-
-=back
-
-=head1 EXAMPLE
-
-The basic material for the preceding section was generated by running
-the sed script
-
- #no autoprint
- s/^.*Warn( *"\([^"]*\)".*$/\1/
- t process
- b
- :process
- s/$!/%s/g
- s/$[_[:alnum:]]\{1,\}/%s/g
- s/\\\\/\\/g
- s/^/=item /
- p
-
-on the program's own text, and piping the output into C<sort -u>.
-
-
-=head1 SED SCRIPT TRANSLATION
-
-If this program is invoked with the name F<s2p> it will act as a
-sed-to-Perl translator. After option processing (all other
-arguments are ignored), a Perl program is printed on standard
-output, which will process the input stream (as read from all
-arguments) in the way defined by the sed script and the option setting
-used for the translation.
-
-=head1 SEE ALSO
-
-perl(1), re_format(7)
-
-=head1 BUGS
-
-The B<l> command will show escape characters (ESC) as `C<\e>', but
-a vertical tab (VT) in octal.
-
-Trailing spaces are truncated from labels in B<:>, B<t> and B<b> commands.
-
-The meaning of an empty regular expression (`C<//>'), as defined by B<sed>,
-is "the last pattern used, at run time". This deviates from the Perl
-interpretation, which will re-use the "last last successfully executed
-regular expression". Since keeping track of pattern usage would create
-terribly cluttered code, and differences would only appear in obscure
-context (where other B<sed> implementations appear to deviate, too),
-the Perl semantics was adopted. Note that common usage of this feature,
-such as in C</abc/s//xyz/>, will work as expected.
-
-Collating elements (of bracket expressions in BREs) are not implemented.
-
-=head1 STANDARDS
-
-This B<sed> implementation conforms to the IEEE Std1003.2-1992 ("POSIX.2")
-definition of B<sed>, and is compatible with the I<OpenBSD>
-implementation, except where otherwise noted (see L<"BUGS">).
-
-=head1 AUTHOR
-
-This Perl implementation of I<sed> was written by Wolfgang Laun,
-I<Wolfgang.Laun@alcatel.at>.
-
-=head1 COPYRIGHT and LICENSE
-
-This program is free and open software. You may use, modify,
-distribute, and sell this program (and any modified variants) in any
-way you wish, provided you do not restrict others from doing the same.
-
-=cut
-