New directory structure:

- simulator source now in 'src' subdirectory
- imported files from 'ext' repository
- support building in arbitrary places, including
outside of the source tree.  See comment at top
of SConstruct file for more details.
Regression tests are temporarily disabled; that
syetem needs more extensive revisions.

SConstruct:
    Update for new directory structure.
    Modify to support build trees that are not subdirectories
    of the source tree.  See comment at top of file for
    more details.
    Regression tests are temporarily disabled.
src/arch/SConscript:
src/arch/isa_parser.py:
src/python/SConscript:
    Update for new directory structure.

--HG--
rename : build/SConstruct => SConstruct
rename : build/default_options/ALPHA_FS => build_opts/ALPHA_FS
rename : build/default_options/ALPHA_FS_TL => build_opts/ALPHA_FS_TL
rename : build/default_options/ALPHA_SE => build_opts/ALPHA_SE
rename : build/default_options/MIPS_SE => build_opts/MIPS_SE
rename : build/default_options/SPARC_SE => build_opts/SPARC_SE
rename : Doxyfile => src/Doxyfile
rename : SConscript => src/SConscript
rename : arch/SConscript => src/arch/SConscript
rename : arch/alpha/SConscript => src/arch/alpha/SConscript
rename : arch/alpha/aout_machdep.h => src/arch/alpha/aout_machdep.h
rename : arch/alpha/arguments.cc => src/arch/alpha/arguments.cc
rename : arch/alpha/arguments.hh => src/arch/alpha/arguments.hh
rename : arch/alpha/ecoff_machdep.h => src/arch/alpha/ecoff_machdep.h
rename : arch/alpha/ev5.cc => src/arch/alpha/ev5.cc
rename : arch/alpha/ev5.hh => src/arch/alpha/ev5.hh
rename : arch/alpha/faults.cc => src/arch/alpha/faults.cc
rename : arch/alpha/faults.hh => src/arch/alpha/faults.hh
rename : arch/alpha/freebsd/system.cc => src/arch/alpha/freebsd/system.cc
rename : arch/alpha/freebsd/system.hh => src/arch/alpha/freebsd/system.hh
rename : arch/alpha/isa/branch.isa => src/arch/alpha/isa/branch.isa
rename : arch/alpha/isa/decoder.isa => src/arch/alpha/isa/decoder.isa
rename : arch/alpha/isa/fp.isa => src/arch/alpha/isa/fp.isa
rename : arch/alpha/isa/int.isa => src/arch/alpha/isa/int.isa
rename : arch/alpha/isa/main.isa => src/arch/alpha/isa/main.isa
rename : arch/alpha/isa/mem.isa => src/arch/alpha/isa/mem.isa
rename : arch/alpha/isa/opcdec.isa => src/arch/alpha/isa/opcdec.isa
rename : arch/alpha/isa/pal.isa => src/arch/alpha/isa/pal.isa
rename : arch/alpha/isa/unimp.isa => src/arch/alpha/isa/unimp.isa
rename : arch/alpha/isa/unknown.isa => src/arch/alpha/isa/unknown.isa
rename : arch/alpha/isa/util.isa => src/arch/alpha/isa/util.isa
rename : arch/alpha/isa_traits.hh => src/arch/alpha/isa_traits.hh
rename : arch/alpha/linux/aligned.hh => src/arch/alpha/linux/aligned.hh
rename : arch/alpha/linux/hwrpb.hh => src/arch/alpha/linux/hwrpb.hh
rename : arch/alpha/linux/linux.cc => src/arch/alpha/linux/linux.cc
rename : arch/alpha/linux/linux.hh => src/arch/alpha/linux/linux.hh
rename : arch/alpha/linux/process.cc => src/arch/alpha/linux/process.cc
rename : arch/alpha/linux/process.hh => src/arch/alpha/linux/process.hh
rename : arch/alpha/linux/system.cc => src/arch/alpha/linux/system.cc
rename : arch/alpha/linux/system.hh => src/arch/alpha/linux/system.hh
rename : arch/alpha/linux/thread_info.hh => src/arch/alpha/linux/thread_info.hh
rename : arch/alpha/linux/threadinfo.hh => src/arch/alpha/linux/threadinfo.hh
rename : arch/alpha/osfpal.cc => src/arch/alpha/osfpal.cc
rename : arch/alpha/osfpal.hh => src/arch/alpha/osfpal.hh
rename : arch/alpha/process.cc => src/arch/alpha/process.cc
rename : arch/alpha/process.hh => src/arch/alpha/process.hh
rename : arch/alpha/regfile.hh => src/arch/alpha/regfile.hh
rename : arch/alpha/stacktrace.cc => src/arch/alpha/stacktrace.cc
rename : arch/alpha/stacktrace.hh => src/arch/alpha/stacktrace.hh
rename : arch/alpha/system.cc => src/arch/alpha/system.cc
rename : arch/alpha/system.hh => src/arch/alpha/system.hh
rename : arch/alpha/tlb.cc => src/arch/alpha/tlb.cc
rename : arch/alpha/tlb.hh => src/arch/alpha/tlb.hh
rename : arch/alpha/tru64/process.cc => src/arch/alpha/tru64/process.cc
rename : arch/alpha/tru64/process.hh => src/arch/alpha/tru64/process.hh
rename : arch/alpha/tru64/system.cc => src/arch/alpha/tru64/system.cc
rename : arch/alpha/tru64/system.hh => src/arch/alpha/tru64/system.hh
rename : arch/alpha/tru64/tru64.cc => src/arch/alpha/tru64/tru64.cc
rename : arch/alpha/tru64/tru64.hh => src/arch/alpha/tru64/tru64.hh
rename : arch/alpha/types.hh => src/arch/alpha/types.hh
rename : arch/alpha/utility.hh => src/arch/alpha/utility.hh
rename : arch/alpha/vtophys.cc => src/arch/alpha/vtophys.cc
rename : arch/alpha/vtophys.hh => src/arch/alpha/vtophys.hh
rename : arch/isa_parser.py => src/arch/isa_parser.py
rename : arch/isa_specific.hh => src/arch/isa_specific.hh
rename : arch/mips/SConscript => src/arch/mips/SConscript
rename : arch/mips/faults.cc => src/arch/mips/faults.cc
rename : arch/mips/faults.hh => src/arch/mips/faults.hh
rename : arch/mips/isa/base.isa => src/arch/mips/isa/base.isa
rename : arch/mips/isa/bitfields.isa => src/arch/mips/isa/bitfields.isa
rename : arch/mips/isa/decoder.isa => src/arch/mips/isa/decoder.isa
rename : arch/mips/isa/formats/basic.isa => src/arch/mips/isa/formats/basic.isa
rename : arch/mips/isa/formats/branch.isa => src/arch/mips/isa/formats/branch.isa
rename : arch/mips/isa/formats/formats.isa => src/arch/mips/isa/formats/formats.isa
rename : arch/mips/isa/formats/fp.isa => src/arch/mips/isa/formats/fp.isa
rename : arch/mips/isa/formats/int.isa => src/arch/mips/isa/formats/int.isa
rename : arch/mips/isa/formats/mem.isa => src/arch/mips/isa/formats/mem.isa
rename : arch/mips/isa/formats/noop.isa => src/arch/mips/isa/formats/noop.isa
rename : arch/mips/isa/formats/tlbop.isa => src/arch/mips/isa/formats/tlbop.isa
rename : arch/mips/isa/formats/trap.isa => src/arch/mips/isa/formats/trap.isa
rename : arch/mips/isa/formats/unimp.isa => src/arch/mips/isa/formats/unimp.isa
rename : arch/mips/isa/formats/unknown.isa => src/arch/mips/isa/formats/unknown.isa
rename : arch/mips/isa/formats/util.isa => src/arch/mips/isa/formats/util.isa
rename : arch/mips/isa/includes.isa => src/arch/mips/isa/includes.isa
rename : arch/mips/isa/main.isa => src/arch/mips/isa/main.isa
rename : arch/mips/isa/operands.isa => src/arch/mips/isa/operands.isa
rename : arch/mips/isa_traits.cc => src/arch/mips/isa_traits.cc
rename : arch/mips/isa_traits.hh => src/arch/mips/isa_traits.hh
rename : arch/mips/linux/linux.cc => src/arch/mips/linux/linux.cc
rename : arch/mips/linux/linux.hh => src/arch/mips/linux/linux.hh
rename : arch/mips/linux/process.cc => src/arch/mips/linux/process.cc
rename : arch/mips/linux/process.hh => src/arch/mips/linux/process.hh
rename : arch/mips/process.cc => src/arch/mips/process.cc
rename : arch/mips/process.hh => src/arch/mips/process.hh
rename : arch/mips/regfile/float_regfile.hh => src/arch/mips/regfile/float_regfile.hh
rename : arch/mips/regfile/int_regfile.hh => src/arch/mips/regfile/int_regfile.hh
rename : arch/mips/regfile/misc_regfile.hh => src/arch/mips/regfile/misc_regfile.hh
rename : arch/mips/regfile/regfile.hh => src/arch/mips/regfile/regfile.hh
rename : arch/mips/stacktrace.hh => src/arch/mips/stacktrace.hh
rename : arch/mips/types.hh => src/arch/mips/types.hh
rename : arch/mips/utility.hh => src/arch/mips/utility.hh
rename : arch/sparc/SConscript => src/arch/sparc/SConscript
rename : arch/sparc/faults.cc => src/arch/sparc/faults.cc
rename : arch/sparc/faults.hh => src/arch/sparc/faults.hh
rename : arch/sparc/isa/base.isa => src/arch/sparc/isa/base.isa
rename : arch/sparc/isa/bitfields.isa => src/arch/sparc/isa/bitfields.isa
rename : arch/sparc/isa/decoder.isa => src/arch/sparc/isa/decoder.isa
rename : arch/sparc/isa/formats.isa => src/arch/sparc/isa/formats.isa
rename : arch/sparc/isa/formats/basic.isa => src/arch/sparc/isa/formats/basic.isa
rename : arch/sparc/isa/formats/branch.isa => src/arch/sparc/isa/formats/branch.isa
rename : arch/sparc/isa/formats/integerop.isa => src/arch/sparc/isa/formats/integerop.isa
rename : arch/sparc/isa/formats/mem.isa => src/arch/sparc/isa/formats/mem.isa
rename : arch/sparc/isa/formats/nop.isa => src/arch/sparc/isa/formats/nop.isa
rename : arch/sparc/isa/formats/priv.isa => src/arch/sparc/isa/formats/priv.isa
rename : arch/sparc/isa/formats/trap.isa => src/arch/sparc/isa/formats/trap.isa
rename : arch/sparc/isa/formats/unknown.isa => src/arch/sparc/isa/formats/unknown.isa
rename : arch/sparc/isa/includes.isa => src/arch/sparc/isa/includes.isa
rename : arch/sparc/isa/main.isa => src/arch/sparc/isa/main.isa
rename : arch/sparc/isa/operands.isa => src/arch/sparc/isa/operands.isa
rename : arch/sparc/isa_traits.hh => src/arch/sparc/isa_traits.hh
rename : arch/sparc/linux/linux.cc => src/arch/sparc/linux/linux.cc
rename : arch/sparc/linux/linux.hh => src/arch/sparc/linux/linux.hh
rename : arch/sparc/linux/process.cc => src/arch/sparc/linux/process.cc
rename : arch/sparc/linux/process.hh => src/arch/sparc/linux/process.hh
rename : arch/sparc/process.cc => src/arch/sparc/process.cc
rename : arch/sparc/process.hh => src/arch/sparc/process.hh
rename : arch/sparc/regfile.hh => src/arch/sparc/regfile.hh
rename : arch/sparc/solaris/process.cc => src/arch/sparc/solaris/process.cc
rename : arch/sparc/solaris/process.hh => src/arch/sparc/solaris/process.hh
rename : arch/sparc/solaris/solaris.cc => src/arch/sparc/solaris/solaris.cc
rename : arch/sparc/solaris/solaris.hh => src/arch/sparc/solaris/solaris.hh
rename : arch/sparc/stacktrace.hh => src/arch/sparc/stacktrace.hh
rename : arch/sparc/system.cc => src/arch/sparc/system.cc
rename : arch/sparc/system.hh => src/arch/sparc/system.hh
rename : arch/sparc/utility.hh => src/arch/sparc/utility.hh
rename : base/bitfield.hh => src/base/bitfield.hh
rename : base/callback.hh => src/base/callback.hh
rename : base/chunk_generator.hh => src/base/chunk_generator.hh
rename : base/circlebuf.cc => src/base/circlebuf.cc
rename : base/circlebuf.hh => src/base/circlebuf.hh
rename : base/compression/lzss_compression.cc => src/base/compression/lzss_compression.cc
rename : base/compression/lzss_compression.hh => src/base/compression/lzss_compression.hh
rename : base/compression/null_compression.hh => src/base/compression/null_compression.hh
rename : base/cprintf.cc => src/base/cprintf.cc
rename : base/cprintf.hh => src/base/cprintf.hh
rename : base/cprintf_formats.hh => src/base/cprintf_formats.hh
rename : base/crc.cc => src/base/crc.cc
rename : base/crc.hh => src/base/crc.hh
rename : base/date.cc => src/base/date.cc
rename : base/dbl_list.hh => src/base/dbl_list.hh
rename : base/endian.hh => src/base/endian.hh
rename : base/fast_alloc.cc => src/base/fast_alloc.cc
rename : base/fast_alloc.hh => src/base/fast_alloc.hh
rename : base/fenv.hh => src/base/fenv.hh
rename : base/fifo_buffer.cc => src/base/fifo_buffer.cc
rename : base/fifo_buffer.hh => src/base/fifo_buffer.hh
rename : base/hashmap.hh => src/base/hashmap.hh
rename : base/hostinfo.cc => src/base/hostinfo.cc
rename : base/hostinfo.hh => src/base/hostinfo.hh
rename : base/hybrid_pred.cc => src/base/hybrid_pred.cc
rename : base/hybrid_pred.hh => src/base/hybrid_pred.hh
rename : base/inet.cc => src/base/inet.cc
rename : base/inet.hh => src/base/inet.hh
rename : base/inifile.cc => src/base/inifile.cc
rename : base/inifile.hh => src/base/inifile.hh
rename : base/intmath.cc => src/base/intmath.cc
rename : base/intmath.hh => src/base/intmath.hh
rename : base/kgdb.h => src/base/kgdb.h
rename : base/loader/aout_object.cc => src/base/loader/aout_object.cc
rename : base/loader/aout_object.hh => src/base/loader/aout_object.hh
rename : base/loader/coff_sym.h => src/base/loader/coff_sym.h
rename : base/loader/coff_symconst.h => src/base/loader/coff_symconst.h
rename : base/loader/ecoff_object.cc => src/base/loader/ecoff_object.cc
rename : base/loader/ecoff_object.hh => src/base/loader/ecoff_object.hh
rename : base/loader/elf_object.cc => src/base/loader/elf_object.cc
rename : base/loader/elf_object.hh => src/base/loader/elf_object.hh
rename : base/loader/exec_aout.h => src/base/loader/exec_aout.h
rename : base/loader/exec_ecoff.h => src/base/loader/exec_ecoff.h
rename : base/loader/object_file.cc => src/base/loader/object_file.cc
rename : base/loader/object_file.hh => src/base/loader/object_file.hh
rename : base/loader/symtab.cc => src/base/loader/symtab.cc
rename : base/loader/symtab.hh => src/base/loader/symtab.hh
rename : base/match.cc => src/base/match.cc
rename : base/match.hh => src/base/match.hh
rename : base/misc.cc => src/base/misc.cc
rename : base/misc.hh => src/base/misc.hh
rename : base/mod_num.hh => src/base/mod_num.hh
rename : base/mysql.cc => src/base/mysql.cc
rename : base/mysql.hh => src/base/mysql.hh
rename : base/output.cc => src/base/output.cc
rename : base/output.hh => src/base/output.hh
rename : base/pollevent.cc => src/base/pollevent.cc
rename : base/pollevent.hh => src/base/pollevent.hh
rename : base/predictor.hh => src/base/predictor.hh
rename : base/random.cc => src/base/random.cc
rename : base/random.hh => src/base/random.hh
rename : base/range.cc => src/base/range.cc
rename : base/range.hh => src/base/range.hh
rename : base/refcnt.hh => src/base/refcnt.hh
rename : base/remote_gdb.cc => src/base/remote_gdb.cc
rename : base/remote_gdb.hh => src/base/remote_gdb.hh
rename : base/res_list.hh => src/base/res_list.hh
rename : base/sat_counter.cc => src/base/sat_counter.cc
rename : base/sat_counter.hh => src/base/sat_counter.hh
rename : base/sched_list.hh => src/base/sched_list.hh
rename : base/socket.cc => src/base/socket.cc
rename : base/socket.hh => src/base/socket.hh
rename : base/statistics.cc => src/base/statistics.cc
rename : base/statistics.hh => src/base/statistics.hh
rename : base/stats/events.cc => src/base/stats/events.cc
rename : base/stats/events.hh => src/base/stats/events.hh
rename : base/stats/flags.hh => src/base/stats/flags.hh
rename : base/stats/mysql.cc => src/base/stats/mysql.cc
rename : base/stats/mysql.hh => src/base/stats/mysql.hh
rename : base/stats/mysql_run.hh => src/base/stats/mysql_run.hh
rename : base/stats/output.hh => src/base/stats/output.hh
rename : base/stats/statdb.cc => src/base/stats/statdb.cc
rename : base/stats/statdb.hh => src/base/stats/statdb.hh
rename : base/stats/text.cc => src/base/stats/text.cc
rename : base/stats/text.hh => src/base/stats/text.hh
rename : base/stats/types.hh => src/base/stats/types.hh
rename : base/stats/visit.cc => src/base/stats/visit.cc
rename : base/stats/visit.hh => src/base/stats/visit.hh
rename : base/str.cc => src/base/str.cc
rename : base/str.hh => src/base/str.hh
rename : base/time.cc => src/base/time.cc
rename : base/time.hh => src/base/time.hh
rename : base/timebuf.hh => src/base/timebuf.hh
rename : base/trace.cc => src/base/trace.cc
rename : base/trace.hh => src/base/trace.hh
rename : base/traceflags.py => src/base/traceflags.py
rename : base/userinfo.cc => src/base/userinfo.cc
rename : base/userinfo.hh => src/base/userinfo.hh
rename : cpu/SConscript => src/cpu/SConscript
rename : cpu/base.cc => src/cpu/base.cc
rename : cpu/base.hh => src/cpu/base.hh
rename : cpu/base_dyn_inst.cc => src/cpu/base_dyn_inst.cc
rename : cpu/base_dyn_inst.hh => src/cpu/base_dyn_inst.hh
rename : cpu/cpu_exec_context.cc => src/cpu/cpu_exec_context.cc
rename : cpu/cpu_exec_context.hh => src/cpu/cpu_exec_context.hh
rename : cpu/cpu_models.py => src/cpu/cpu_models.py
rename : cpu/exec_context.hh => src/cpu/exec_context.hh
rename : cpu/exetrace.cc => src/cpu/exetrace.cc
rename : cpu/exetrace.hh => src/cpu/exetrace.hh
rename : cpu/inst_seq.hh => src/cpu/inst_seq.hh
rename : cpu/intr_control.cc => src/cpu/intr_control.cc
rename : cpu/intr_control.hh => src/cpu/intr_control.hh
rename : cpu/memtest/memtest.cc => src/cpu/memtest/memtest.cc
rename : cpu/memtest/memtest.hh => src/cpu/memtest/memtest.hh
rename : cpu/o3/2bit_local_pred.cc => src/cpu/o3/2bit_local_pred.cc
rename : cpu/o3/2bit_local_pred.hh => src/cpu/o3/2bit_local_pred.hh
rename : cpu/o3/alpha_cpu.cc => src/cpu/o3/alpha_cpu.cc
rename : cpu/o3/alpha_cpu.hh => src/cpu/o3/alpha_cpu.hh
rename : cpu/o3/alpha_cpu_builder.cc => src/cpu/o3/alpha_cpu_builder.cc
rename : cpu/o3/alpha_cpu_impl.hh => src/cpu/o3/alpha_cpu_impl.hh
rename : cpu/o3/alpha_dyn_inst.cc => src/cpu/o3/alpha_dyn_inst.cc
rename : cpu/o3/alpha_dyn_inst.hh => src/cpu/o3/alpha_dyn_inst.hh
rename : cpu/o3/alpha_dyn_inst_impl.hh => src/cpu/o3/alpha_dyn_inst_impl.hh
rename : cpu/o3/alpha_impl.hh => src/cpu/o3/alpha_impl.hh
rename : cpu/o3/alpha_params.hh => src/cpu/o3/alpha_params.hh
rename : cpu/o3/bpred_unit.cc => src/cpu/o3/bpred_unit.cc
rename : cpu/o3/bpred_unit.hh => src/cpu/o3/bpred_unit.hh
rename : cpu/o3/bpred_unit_impl.hh => src/cpu/o3/bpred_unit_impl.hh
rename : cpu/o3/btb.cc => src/cpu/o3/btb.cc
rename : cpu/o3/btb.hh => src/cpu/o3/btb.hh
rename : cpu/o3/comm.hh => src/cpu/o3/comm.hh
rename : cpu/o3/commit.cc => src/cpu/o3/commit.cc
rename : cpu/o3/commit.hh => src/cpu/o3/commit.hh
rename : cpu/o3/commit_impl.hh => src/cpu/o3/commit_impl.hh
rename : cpu/o3/cpu.cc => src/cpu/o3/cpu.cc
rename : cpu/o3/cpu.hh => src/cpu/o3/cpu.hh
rename : cpu/o3/cpu_policy.hh => src/cpu/o3/cpu_policy.hh
rename : cpu/o3/decode.cc => src/cpu/o3/decode.cc
rename : cpu/o3/decode.hh => src/cpu/o3/decode.hh
rename : cpu/o3/decode_impl.hh => src/cpu/o3/decode_impl.hh
rename : cpu/o3/fetch.cc => src/cpu/o3/fetch.cc
rename : cpu/o3/fetch.hh => src/cpu/o3/fetch.hh
rename : cpu/o3/fetch_impl.hh => src/cpu/o3/fetch_impl.hh
rename : cpu/o3/free_list.cc => src/cpu/o3/free_list.cc
rename : cpu/o3/free_list.hh => src/cpu/o3/free_list.hh
rename : cpu/o3/iew.cc => src/cpu/o3/iew.cc
rename : cpu/o3/iew.hh => src/cpu/o3/iew.hh
rename : cpu/o3/iew_impl.hh => src/cpu/o3/iew_impl.hh
rename : cpu/o3/inst_queue.cc => src/cpu/o3/inst_queue.cc
rename : cpu/o3/inst_queue.hh => src/cpu/o3/inst_queue.hh
rename : cpu/o3/inst_queue_impl.hh => src/cpu/o3/inst_queue_impl.hh
rename : cpu/o3/mem_dep_unit.cc => src/cpu/o3/mem_dep_unit.cc
rename : cpu/o3/mem_dep_unit.hh => src/cpu/o3/mem_dep_unit.hh
rename : cpu/o3/mem_dep_unit_impl.hh => src/cpu/o3/mem_dep_unit_impl.hh
rename : cpu/o3/ras.cc => src/cpu/o3/ras.cc
rename : cpu/o3/ras.hh => src/cpu/o3/ras.hh
rename : cpu/o3/regfile.hh => src/cpu/o3/regfile.hh
rename : cpu/o3/rename.cc => src/cpu/o3/rename.cc
rename : cpu/o3/rename.hh => src/cpu/o3/rename.hh
rename : cpu/o3/rename_impl.hh => src/cpu/o3/rename_impl.hh
rename : cpu/o3/rename_map.cc => src/cpu/o3/rename_map.cc
rename : cpu/o3/rename_map.hh => src/cpu/o3/rename_map.hh
rename : cpu/o3/rob.cc => src/cpu/o3/rob.cc
rename : cpu/o3/rob.hh => src/cpu/o3/rob.hh
rename : cpu/o3/rob_impl.hh => src/cpu/o3/rob_impl.hh
rename : cpu/o3/sat_counter.cc => src/cpu/o3/sat_counter.cc
rename : cpu/o3/sat_counter.hh => src/cpu/o3/sat_counter.hh
rename : cpu/o3/store_set.cc => src/cpu/o3/store_set.cc
rename : cpu/o3/store_set.hh => src/cpu/o3/store_set.hh
rename : cpu/o3/tournament_pred.cc => src/cpu/o3/tournament_pred.cc
rename : cpu/o3/tournament_pred.hh => src/cpu/o3/tournament_pred.hh
rename : cpu/op_class.cc => src/cpu/op_class.cc
rename : cpu/op_class.hh => src/cpu/op_class.hh
rename : cpu/ozone/cpu.cc => src/cpu/ozone/cpu.cc
rename : cpu/ozone/cpu.hh => src/cpu/ozone/cpu.hh
rename : cpu/ozone/cpu_impl.hh => src/cpu/ozone/cpu_impl.hh
rename : cpu/ozone/ea_list.cc => src/cpu/ozone/ea_list.cc
rename : cpu/ozone/ea_list.hh => src/cpu/ozone/ea_list.hh
rename : cpu/pc_event.cc => src/cpu/pc_event.cc
rename : cpu/pc_event.hh => src/cpu/pc_event.hh
rename : cpu/profile.cc => src/cpu/profile.cc
rename : cpu/profile.hh => src/cpu/profile.hh
rename : cpu/simple/atomic.cc => src/cpu/simple/atomic.cc
rename : cpu/simple/atomic.hh => src/cpu/simple/atomic.hh
rename : cpu/simple/base.cc => src/cpu/simple/base.cc
rename : cpu/simple/base.hh => src/cpu/simple/base.hh
rename : cpu/simple/timing.cc => src/cpu/simple/timing.cc
rename : cpu/simple/timing.hh => src/cpu/simple/timing.hh
rename : cpu/smt.hh => src/cpu/smt.hh
rename : cpu/static_inst.cc => src/cpu/static_inst.cc
rename : cpu/static_inst.hh => src/cpu/static_inst.hh
rename : cpu/trace/opt_cpu.cc => src/cpu/trace/opt_cpu.cc
rename : cpu/trace/opt_cpu.hh => src/cpu/trace/opt_cpu.hh
rename : cpu/trace/reader/ibm_reader.cc => src/cpu/trace/reader/ibm_reader.cc
rename : cpu/trace/reader/ibm_reader.hh => src/cpu/trace/reader/ibm_reader.hh
rename : cpu/trace/reader/itx_reader.cc => src/cpu/trace/reader/itx_reader.cc
rename : cpu/trace/reader/itx_reader.hh => src/cpu/trace/reader/itx_reader.hh
rename : cpu/trace/reader/m5_reader.cc => src/cpu/trace/reader/m5_reader.cc
rename : cpu/trace/reader/m5_reader.hh => src/cpu/trace/reader/m5_reader.hh
rename : cpu/trace/reader/mem_trace_reader.cc => src/cpu/trace/reader/mem_trace_reader.cc
rename : cpu/trace/reader/mem_trace_reader.hh => src/cpu/trace/reader/mem_trace_reader.hh
rename : cpu/trace/trace_cpu.cc => src/cpu/trace/trace_cpu.cc
rename : cpu/trace/trace_cpu.hh => src/cpu/trace/trace_cpu.hh
rename : dev/alpha_access.h => src/dev/alpha_access.h
rename : dev/alpha_console.cc => src/dev/alpha_console.cc
rename : dev/alpha_console.hh => src/dev/alpha_console.hh
rename : dev/baddev.cc => src/dev/baddev.cc
rename : dev/baddev.hh => src/dev/baddev.hh
rename : dev/disk_image.cc => src/dev/disk_image.cc
rename : dev/disk_image.hh => src/dev/disk_image.hh
rename : dev/etherbus.cc => src/dev/etherbus.cc
rename : dev/etherbus.hh => src/dev/etherbus.hh
rename : dev/etherdump.cc => src/dev/etherdump.cc
rename : dev/etherdump.hh => src/dev/etherdump.hh
rename : dev/etherint.cc => src/dev/etherint.cc
rename : dev/etherint.hh => src/dev/etherint.hh
rename : dev/etherlink.cc => src/dev/etherlink.cc
rename : dev/etherlink.hh => src/dev/etherlink.hh
rename : dev/etherpkt.cc => src/dev/etherpkt.cc
rename : dev/etherpkt.hh => src/dev/etherpkt.hh
rename : dev/ethertap.cc => src/dev/ethertap.cc
rename : dev/ethertap.hh => src/dev/ethertap.hh
rename : dev/ide_atareg.h => src/dev/ide_atareg.h
rename : dev/ide_ctrl.cc => src/dev/ide_ctrl.cc
rename : dev/ide_ctrl.hh => src/dev/ide_ctrl.hh
rename : dev/ide_disk.cc => src/dev/ide_disk.cc
rename : dev/ide_disk.hh => src/dev/ide_disk.hh
rename : dev/ide_wdcreg.h => src/dev/ide_wdcreg.h
rename : dev/io_device.cc => src/dev/io_device.cc
rename : dev/io_device.hh => src/dev/io_device.hh
rename : dev/isa_fake.cc => src/dev/isa_fake.cc
rename : dev/isa_fake.hh => src/dev/isa_fake.hh
rename : dev/ns_gige.cc => src/dev/ns_gige.cc
rename : dev/ns_gige.hh => src/dev/ns_gige.hh
rename : dev/ns_gige_reg.h => src/dev/ns_gige_reg.h
rename : dev/pciconfigall.cc => src/dev/pciconfigall.cc
rename : dev/pciconfigall.hh => src/dev/pciconfigall.hh
rename : dev/pcidev.cc => src/dev/pcidev.cc
rename : dev/pcidev.hh => src/dev/pcidev.hh
rename : dev/pcireg.h => src/dev/pcireg.h
rename : dev/pitreg.h => src/dev/pitreg.h
rename : dev/pktfifo.cc => src/dev/pktfifo.cc
rename : dev/pktfifo.hh => src/dev/pktfifo.hh
rename : dev/platform.cc => src/dev/platform.cc
rename : dev/platform.hh => src/dev/platform.hh
rename : dev/rtcreg.h => src/dev/rtcreg.h
rename : dev/simconsole.cc => src/dev/simconsole.cc
rename : dev/simconsole.hh => src/dev/simconsole.hh
rename : dev/simple_disk.cc => src/dev/simple_disk.cc
rename : dev/simple_disk.hh => src/dev/simple_disk.hh
rename : dev/sinic.cc => src/dev/sinic.cc
rename : dev/sinic.hh => src/dev/sinic.hh
rename : dev/sinicreg.hh => src/dev/sinicreg.hh
rename : dev/tsunami.cc => src/dev/tsunami.cc
rename : dev/tsunami.hh => src/dev/tsunami.hh
rename : dev/tsunami_cchip.cc => src/dev/tsunami_cchip.cc
rename : dev/tsunami_cchip.hh => src/dev/tsunami_cchip.hh
rename : dev/tsunami_io.cc => src/dev/tsunami_io.cc
rename : dev/tsunami_io.hh => src/dev/tsunami_io.hh
rename : dev/tsunami_pchip.cc => src/dev/tsunami_pchip.cc
rename : dev/tsunami_pchip.hh => src/dev/tsunami_pchip.hh
rename : dev/tsunamireg.h => src/dev/tsunamireg.h
rename : dev/uart.cc => src/dev/uart.cc
rename : dev/uart.hh => src/dev/uart.hh
rename : dev/uart8250.cc => src/dev/uart8250.cc
rename : dev/uart8250.hh => src/dev/uart8250.hh
rename : kern/kernel_stats.cc => src/kern/kernel_stats.cc
rename : kern/kernel_stats.hh => src/kern/kernel_stats.hh
rename : kern/linux/events.cc => src/kern/linux/events.cc
rename : kern/linux/events.hh => src/kern/linux/events.hh
rename : kern/linux/linux.hh => src/kern/linux/linux.hh
rename : kern/linux/linux_syscalls.cc => src/kern/linux/linux_syscalls.cc
rename : kern/linux/linux_syscalls.hh => src/kern/linux/linux_syscalls.hh
rename : kern/linux/printk.cc => src/kern/linux/printk.cc
rename : kern/linux/printk.hh => src/kern/linux/printk.hh
rename : kern/linux/sched.hh => src/kern/linux/sched.hh
rename : kern/solaris/solaris.hh => src/kern/solaris/solaris.hh
rename : kern/system_events.cc => src/kern/system_events.cc
rename : kern/system_events.hh => src/kern/system_events.hh
rename : kern/tru64/dump_mbuf.cc => src/kern/tru64/dump_mbuf.cc
rename : kern/tru64/dump_mbuf.hh => src/kern/tru64/dump_mbuf.hh
rename : kern/tru64/mbuf.hh => src/kern/tru64/mbuf.hh
rename : kern/tru64/printf.cc => src/kern/tru64/printf.cc
rename : kern/tru64/printf.hh => src/kern/tru64/printf.hh
rename : kern/tru64/tru64.hh => src/kern/tru64/tru64.hh
rename : kern/tru64/tru64_events.cc => src/kern/tru64/tru64_events.cc
rename : kern/tru64/tru64_events.hh => src/kern/tru64/tru64_events.hh
rename : kern/tru64/tru64_syscalls.cc => src/kern/tru64/tru64_syscalls.cc
rename : kern/tru64/tru64_syscalls.hh => src/kern/tru64/tru64_syscalls.hh
rename : mem/bridge.cc => src/mem/bridge.cc
rename : mem/bridge.hh => src/mem/bridge.hh
rename : mem/bus.cc => src/mem/bus.cc
rename : mem/bus.hh => src/mem/bus.hh
rename : mem/cache/prefetch/tagged_prefetcher_impl.hh => src/mem/cache/prefetch/tagged_prefetcher_impl.hh
rename : mem/config/prefetch.hh => src/mem/config/prefetch.hh
rename : mem/mem_object.cc => src/mem/mem_object.cc
rename : mem/mem_object.hh => src/mem/mem_object.hh
rename : mem/packet.cc => src/mem/packet.cc
rename : mem/packet.hh => src/mem/packet.hh
rename : mem/page_table.cc => src/mem/page_table.cc
rename : mem/page_table.hh => src/mem/page_table.hh
rename : mem/physical.cc => src/mem/physical.cc
rename : mem/physical.hh => src/mem/physical.hh
rename : mem/port.cc => src/mem/port.cc
rename : mem/port.hh => src/mem/port.hh
rename : mem/request.hh => src/mem/request.hh
rename : mem/translating_port.cc => src/mem/translating_port.cc
rename : mem/translating_port.hh => src/mem/translating_port.hh
rename : mem/vport.cc => src/mem/vport.cc
rename : mem/vport.hh => src/mem/vport.hh
rename : python/SConscript => src/python/SConscript
rename : python/m5/__init__.py => src/python/m5/__init__.py
rename : python/m5/config.py => src/python/m5/config.py
rename : python/m5/convert.py => src/python/m5/convert.py
rename : python/m5/multidict.py => src/python/m5/multidict.py
rename : python/m5/objects/AlphaConsole.py => src/python/m5/objects/AlphaConsole.py
rename : python/m5/objects/AlphaFullCPU.py => src/python/m5/objects/AlphaFullCPU.py
rename : python/m5/objects/AlphaTLB.py => src/python/m5/objects/AlphaTLB.py
rename : python/m5/objects/BadDevice.py => src/python/m5/objects/BadDevice.py
rename : python/m5/objects/BaseCPU.py => src/python/m5/objects/BaseCPU.py
rename : python/m5/objects/BaseCache.py => src/python/m5/objects/BaseCache.py
rename : python/m5/objects/Bridge.py => src/python/m5/objects/Bridge.py
rename : python/m5/objects/Bus.py => src/python/m5/objects/Bus.py
rename : python/m5/objects/CoherenceProtocol.py => src/python/m5/objects/CoherenceProtocol.py
rename : python/m5/objects/Device.py => src/python/m5/objects/Device.py
rename : python/m5/objects/DiskImage.py => src/python/m5/objects/DiskImage.py
rename : python/m5/objects/Ethernet.py => src/python/m5/objects/Ethernet.py
rename : python/m5/objects/Ide.py => src/python/m5/objects/Ide.py
rename : python/m5/objects/IntrControl.py => src/python/m5/objects/IntrControl.py
rename : python/m5/objects/MemObject.py => src/python/m5/objects/MemObject.py
rename : python/m5/objects/MemTest.py => src/python/m5/objects/MemTest.py
rename : python/m5/objects/Pci.py => src/python/m5/objects/Pci.py
rename : python/m5/objects/PhysicalMemory.py => src/python/m5/objects/PhysicalMemory.py
rename : python/m5/objects/Platform.py => src/python/m5/objects/Platform.py
rename : python/m5/objects/Process.py => src/python/m5/objects/Process.py
rename : python/m5/objects/Repl.py => src/python/m5/objects/Repl.py
rename : python/m5/objects/Root.py => src/python/m5/objects/Root.py
rename : python/m5/objects/SimConsole.py => src/python/m5/objects/SimConsole.py
rename : python/m5/objects/SimpleDisk.py => src/python/m5/objects/SimpleDisk.py
rename : python/m5/objects/System.py => src/python/m5/objects/System.py
rename : python/m5/objects/Tsunami.py => src/python/m5/objects/Tsunami.py
rename : python/m5/objects/Uart.py => src/python/m5/objects/Uart.py
rename : python/m5/smartdict.py => src/python/m5/smartdict.py
rename : sim/async.hh => src/sim/async.hh
rename : sim/builder.cc => src/sim/builder.cc
rename : sim/builder.hh => src/sim/builder.hh
rename : sim/byteswap.hh => src/sim/byteswap.hh
rename : sim/debug.cc => src/sim/debug.cc
rename : sim/debug.hh => src/sim/debug.hh
rename : sim/eventq.cc => src/sim/eventq.cc
rename : sim/eventq.hh => src/sim/eventq.hh
rename : sim/faults.cc => src/sim/faults.cc
rename : sim/faults.hh => src/sim/faults.hh
rename : sim/host.hh => src/sim/host.hh
rename : sim/main.cc => src/sim/main.cc
rename : sim/param.cc => src/sim/param.cc
rename : sim/param.hh => src/sim/param.hh
rename : sim/process.cc => src/sim/process.cc
rename : sim/process.hh => src/sim/process.hh
rename : sim/pseudo_inst.cc => src/sim/pseudo_inst.cc
rename : sim/pseudo_inst.hh => src/sim/pseudo_inst.hh
rename : sim/root.cc => src/sim/root.cc
rename : sim/serialize.cc => src/sim/serialize.cc
rename : sim/serialize.hh => src/sim/serialize.hh
rename : sim/sim_events.cc => src/sim/sim_events.cc
rename : sim/sim_events.hh => src/sim/sim_events.hh
rename : sim/sim_exit.hh => src/sim/sim_exit.hh
rename : sim/sim_object.cc => src/sim/sim_object.cc
rename : sim/sim_object.hh => src/sim/sim_object.hh
rename : sim/startup.cc => src/sim/startup.cc
rename : sim/startup.hh => src/sim/startup.hh
rename : sim/stat_control.cc => src/sim/stat_control.cc
rename : sim/stat_control.hh => src/sim/stat_control.hh
rename : sim/stats.hh => src/sim/stats.hh
rename : sim/syscall_emul.cc => src/sim/syscall_emul.cc
rename : sim/syscall_emul.hh => src/sim/syscall_emul.hh
rename : sim/system.cc => src/sim/system.cc
rename : sim/system.hh => src/sim/system.hh
rename : sim/vptr.hh => src/sim/vptr.hh
rename : test/Makefile => src/unittest/Makefile
rename : test/bitvectest.cc => src/unittest/bitvectest.cc
rename : test/circletest.cc => src/unittest/circletest.cc
rename : test/cprintftest.cc => src/unittest/cprintftest.cc
rename : test/foo.ini => src/unittest/foo.ini
rename : test/genini.py => src/unittest/genini.py
rename : test/initest.cc => src/unittest/initest.cc
rename : test/initest.ini => src/unittest/initest.ini
rename : test/lru_test.cc => src/unittest/lru_test.cc
rename : test/nmtest.cc => src/unittest/nmtest.cc
rename : test/offtest.cc => src/unittest/offtest.cc
rename : test/paramtest.cc => src/unittest/paramtest.cc
rename : test/rangetest.cc => src/unittest/rangetest.cc
rename : test/sized_test.cc => src/unittest/sized_test.cc
rename : test/stattest.cc => src/unittest/stattest.cc
rename : test/strnumtest.cc => src/unittest/strnumtest.cc
rename : test/symtest.cc => src/unittest/symtest.cc
rename : test/tokentest.cc => src/unittest/tokentest.cc
rename : test/tracetest.cc => src/unittest/tracetest.cc
extra : convert_revision : cab6a5271ca1b368193cd948e5d3dcc47ab1bd48
This commit is contained in:
Steve Reinhardt 2006-05-22 14:29:33 -04:00
parent 86777c9db1
commit ba2eae5d52
649 changed files with 11034 additions and 266 deletions

View file

@ -30,14 +30,31 @@
#
# SCons top-level build description (SConstruct) file.
#
# To build M5, you need a directory with three things:
# 1. A copy of this file (named SConstruct).
# 2. A link named 'm5' to the top of the M5 simulator source tree.
# 3. A link named 'ext' to the top of the M5 external source tree.
# While in this directory ('m5'), just type 'scons' to build the default
# configuration (see below), or type 'scons build/<CONFIG>/<binary>'
# to build some other configuration (e.g., 'build/ALPHA_FS/m5.opt' for
# the optimized full-system version).
#
# Then type 'scons' to build the default configuration (see below), or
# 'scons <CONFIG>/<binary>' to build some other configuration (e.g.,
# 'ALPHA_FS/m5.opt' for the optimized full-system version).
# You can build M5 in a different directory as long as there is a
# 'build/<CONFIG>' somewhere along the target path. The build system
# expdects that all configs under the same build directory are being
# built for the same host system.
#
# Examples:
# These two commands are equivalent. The '-u' option tells scons to
# search up the directory tree for this SConstruct file.
# % cd <path-to-src>/m5 ; scons build/ALPHA_FS/m5.debug
# % cd <path-to-src>/m5/build/ALPHA_FS; scons -u m5.debug
# These two commands are equivalent and demonstrate building in a
# directory outside of the source tree. The '-C' option tells scons
# to chdir to the specified directory to find this SConstruct file.
# % cd <path-to-src>/m5 ; scons /local/foo/build/ALPHA_FS/m5.debug
# % cd /local/foo/build/ALPHA_FS; scons -C <path-to-src>/m5 m5.debug
#
# You can use 'scons -H' to print scons options. If you're in this
# 'm5' directory (or use -u or -C to tell scons where to find this
# file), you can use 'scons -h' to print all the M5-specific build
# options as well.
#
###################################################
@ -47,104 +64,60 @@ import os
# Check for recent-enough Python and SCons versions
EnsurePythonVersion(2,3)
EnsureSConsVersion(0,96)
EnsureSConsVersion(0,96,91)
# The absolute path to the current directory (where this file lives).
ROOT = Dir('.').abspath
# Paths to the M5 and external source trees (local symlinks).
SRCDIR = os.path.join(ROOT, 'm5')
EXT_SRCDIR = os.path.join(ROOT, 'ext')
# Check for 'm5' and 'ext' links, die if they don't exist.
if not os.path.isdir(SRCDIR):
print "Error: '%s' must be a link to the M5 source tree." % SRCDIR
Exit(1)
if not os.path.isdir('ext'):
print "Error: '%s' must be a link to the M5 external source tree." \
% EXT_SRCDIR
Exit(1)
# Paths to the M5 and external source trees.
SRCDIR = os.path.join(ROOT, 'src')
# tell python where to find m5 python code
sys.path.append(os.path.join(SRCDIR, 'python'))
sys.path.append(os.path.join(ROOT, 'src/python'))
###################################################
#
# Figure out which configurations to set up.
#
#
# It's prohibitive to do all the combinations of base configurations
# and options, so we have to infer which ones the user wants.
#
# 1. If there are command-line targets, the configuration(s) are inferred
# from the directories of those targets. If scons was invoked from a
# subdirectory (using 'scons -u'), those targets have to be
# interpreted relative to that subdirectory.
#
# 2. If there are no command-line targets, and scons was invoked from a
# subdirectory (using 'scons -u'), the configuration is inferred from
# the name of the subdirectory.
#
# 3. If there are no command-line targets and scons was invoked from
# the root build directory, a default configuration is used. The
# built-in default is ALPHA_SE, but this can be overridden by setting the
# M5_DEFAULT_CONFIG shell environment veriable.
#
# In cases 2 & 3, the specific file target defaults to 'm5.debug', but
# this can be overridden by setting the M5_DEFAULT_BINARY shell
# environment veriable.
# Figure out which configurations to set up based on the path(s) of
# the target(s).
#
###################################################
# Find default configuration & binary.
default_config = os.environ.get('M5_DEFAULT_CONFIG', 'ALPHA_SE')
default_binary = os.environ.get('M5_DEFAULT_BINARY', 'm5.debug')
Default(os.environ.get('M5_DEFAULT_BINARY', 'build/ALPHA_SE/m5.debug'))
# Ask SCons which directory it was invoked from. If you invoke SCons
# from a subdirectory you must use the '-u' flag.
# Ask SCons which directory it was invoked from.
launch_dir = GetLaunchDir()
# Build a list 'my_targets' of all the targets relative to ROOT.
if launch_dir == ROOT:
# invoked from root build dir
if len(COMMAND_LINE_TARGETS) != 0:
# easy: use specified targets as is
my_targets = COMMAND_LINE_TARGETS
else:
# default target (ALPHA_SE/m5.debug, unless overridden)
target = os.path.join(default_config, default_binary)
my_targets = [target]
Default(target)
else:
# invoked from subdirectory
if not launch_dir.startswith(ROOT):
print "Error: launch dir (%s) not a subdirectory of ROOT (%s)!" \
(launch_dir, ROOT)
# Make targets relative to invocation directory
abs_targets = map(lambda x: os.path.normpath(os.path.join(launch_dir, str(x))),
BUILD_TARGETS)
# helper function: find last occurrence of element in list
def rfind(l, elt, offs = -1):
for i in range(len(l)+offs, 0, -1):
if l[i] == elt:
return i
raise ValueError, "element not found"
# Each target must have 'build' in the interior of the path; the
# directory below this will determine the build parameters. For
# example, for target 'foo/bar/build/ALPHA_SE/arch/alpha/blah.do' we
# recognize that ALPHA_SE specifies the configuration because it
# follow 'build' in the bulid path.
# Generate a list of the unique configs that the collected targets
# reference.
build_paths = []
for t in abs_targets:
path_dirs = t.split('/')
try:
build_top = rfind(path_dirs, 'build', -2)
except:
print "Error: no non-leaf 'build' dir found on target path", t
Exit(1)
# make launch_dir relative to ROOT (strip ROOT plus slash off front)
launch_dir = launch_dir[len(ROOT)+1:]
if len(COMMAND_LINE_TARGETS) != 0:
# make specified targets relative to ROOT
my_targets = map(lambda x: os.path.join(launch_dir, x),
COMMAND_LINE_TARGETS)
else:
# build default binary (m5.debug, unless overridden) using the
# config inferred by the invocation directory (the first
# subdirectory after ROOT)
target = os.path.join(launch_dir.split('/')[0], default_binary)
my_targets = [target]
Default(target)
# Normalize target paths (gets rid of '..' in the middle, etc.)
my_targets = map(os.path.normpath, my_targets)
# Generate a list of the unique configs that the collected targets reference.
build_dirs = []
for t in my_targets:
dir = t.split('/')[0]
if dir not in build_dirs:
build_dirs.append(dir)
config_dir = os.path.join('/',*path_dirs[:build_top+2])
if config_dir not in build_paths:
build_paths.append(config_dir)
###################################################
#
@ -155,8 +128,7 @@ for t in my_targets:
env = Environment(ENV = os.environ, # inherit user's environment vars
ROOT = ROOT,
SRCDIR = SRCDIR,
EXT_SRCDIR = EXT_SRCDIR)
SRCDIR = SRCDIR)
env.SConsignFile("sconsign")
@ -166,8 +138,8 @@ env.SConsignFile("sconsign")
if False:
env.TargetSignatures('content')
# M5_EXT is used by isa_parser.py to find the PLY package.
env.Append(ENV = { 'M5_EXT' : EXT_SRCDIR })
# M5_PLY is used by isa_parser.py to find the PLY package.
env.Append(ENV = { 'M5_PLY' : Dir('ext/ply') })
# Set up default C++ compiler flags
env.Append(CCFLAGS='-pipe')
@ -176,7 +148,7 @@ env.Append(CCFLAGS=Split('-Wall -Wno-sign-compare -Werror -Wundef'))
if sys.platform == 'cygwin':
# cygwin has some header file issues...
env.Append(CCFLAGS=Split("-Wno-uninitialized"))
env.Append(CPPPATH=[os.path.join(EXT_SRCDIR + '/dnet')])
env.Append(CPPPATH=[Dir('ext/dnet')])
# Default libraries
env.Append(LIBS=['z'])
@ -277,7 +249,7 @@ env.NoAction = Action(no_action, None)
# libelf build is described in its own SConscript file.
# SConscript-global is the build in build/libelf shared among all
# configs.
env.SConscript('m5/libelf/SConscript-global', exports = 'env')
env.SConscript('src/libelf/SConscript-global', exports = 'env')
###################################################
#
@ -334,34 +306,44 @@ Usage: scons [scons options] [build options] [target(s)]
'''
for build_dir in build_dirs:
for build_path in build_paths:
print "Building in", build_path
# build_dir is the tail component of build path, and is used to
# determine the build parameters (e.g., 'ALPHA_SE')
(build_root, build_dir) = os.path.split(build_path)
# Make a copy of the default environment to use for this config.
env = base_env.Copy()
# Record what build_dir was in the environment
env.Append(BUILD_DIR=build_dir);
# Set env according to the build directory config.
# Set env options according to the build directory config.
sticky_opts.files = []
# Name of default options file is taken from 'default=' on command
# line if set, otherwise name of build dir.
default_options_file = os.path.join('default_options',
ARGUMENTS.get('default', build_dir))
if os.path.isfile(default_options_file):
sticky_opts.files.append(default_options_file)
current_options_file = os.path.join('options', build_dir)
if os.path.isfile(current_options_file):
sticky_opts.files.append(current_options_file)
# Options for $BUILD_ROOT/$BUILD_DIR are stored in
# $BUILD_ROOT/options/$BUILD_DIR so you can nuke
# $BUILD_ROOT/$BUILD_DIR without losing your options settings.
current_opts_file = os.path.join(build_root, 'options', build_dir)
if os.path.isfile(current_opts_file):
sticky_opts.files.append(current_opts_file)
print "Using saved options file %s" % current_opts_file
else:
# if file doesn't exist, make sure at least the directory is there
# so we can create it later
opt_dir = os.path.dirname(current_options_file)
# Build dir-specific options file doesn't exist.
# Make sure the directory is there so we can create it later
opt_dir = os.path.dirname(current_opts_file)
if not os.path.isdir(opt_dir):
os.mkdir(opt_dir)
if not sticky_opts.files:
print "%s: No options file found in options, using defaults." \
% build_dir
# Get default build options from source tree. Options are
# normally determined by name of $BUILD_DIR, but can be
# overriden by 'default=' arg on command line.
default_opts_file = os.path.join('build_opts',
ARGUMENTS.get('default', build_dir))
if os.path.isfile(default_opts_file):
sticky_opts.files.append(default_opts_file)
print "Options file %s not found,\n using defaults in %s" \
% (current_opts_file, default_opts_file)
else:
print "Error: cannot find options file %s or %s" \
% (current_opts_file, default_opts_file)
Exit(1)
# Apply current option settings to env
sticky_opts.Update(env)
@ -397,7 +379,7 @@ for build_dir in build_dirs:
env.ParseConfig(mysql_config_include)
# Save sticky option settings back to current options file
sticky_opts.Save(current_options_file, env)
sticky_opts.Save(current_opts_file, env)
# Do this after we save setting back, or else we'll tack on an
# extra 'qdo' every time we run scons.
@ -411,14 +393,14 @@ for build_dir in build_dirs:
# The m5/SConscript file sets up the build rules in 'env' according
# to the configured options. It returns a list of environments,
# one for each variant build (debug, opt, etc.)
envList = SConscript('m5/SConscript', build_dir = build_dir,
envList = SConscript('src/SConscript', build_dir = build_path,
exports = 'env', duplicate = False)
# Set up the regression tests for each build.
for e in envList:
SConscript('m5-test/SConscript',
build_dir = os.path.join(build_dir, 'test', e.Label),
exports = { 'env' : e }, duplicate = False)
# for e in envList:
# SConscript('m5-test/SConscript',
# build_dir = os.path.join(build_dir, 'test', e.Label),
# exports = { 'env' : e }, duplicate = False)
Help(help_text)

View file

@ -1,48 +0,0 @@
////////////////////////////////////////////////////////////////////
//
// Bitfield definitions.
//
// Bitfields are shared liberally between instruction formats, so they are
// simply defined alphabetically
def bitfield A <29>;
def bitfield BPCC <21:20>; // for BPcc & FBPcc
def bitfield FCMPCC <26:56>; // for FCMP & FCMPEa
def bitfield FMOVCC <13:11>; // for FMOVcc
def bitfield CC <12:11>; // for MOVcc & Tcc
def bitfield MOVCC3 <18>; // also for MOVcc
def bitfield CMASK <6:4>;
def bitfield COND2 <28:25>;
def bitfield COND4 <17:14>;
def bitfield D16HI <21:20>;
def bitfield D16LO <13:0>;
def bitfield DISP19 <18:0>;
def bitfield DISP22 <21:0>;
def bitfield DISP30 <29:0>;
def bitfield FCN <29:26>;
def bitfield I <13>;
def bitfield IMM_ASI <12:5>;
def bitfield IMM22 <21:0>;
def bitfield MMASK <3:0>;
def bitfield OP <31:30>;
def bitfield OP2 <24:22>;
def bitfield OP3 <24:19>;
def bitfield OPF <13:5>;
def bitfield OPF_CC <13:11>;
def bitfield OPF_LOW5 <9:5>;
def bitfield OPF_LOW6 <10:5>;
def bitfield P <19>;
def bitfield RCOND2 <27:25>;
def bitfield RCOND3 <12:10>;
def bitfield RCOND4 <12:10>;
def bitfield RD <29:25>;
def bitfield RS1 <18:14>;
def bitfield RS2 <4:0>;
def bitfield SHCNT32 <4:0>;
def bitfield SHCNT64 <5:0>;
def bitfield SIMM10 <9:0>;
def bitfield SIMM11 <10:0>;
def bitfield SIMM13 <12:0>;
def bitfield SW_TRAP <7:0>;
def bitfield X <12>;

View file

@ -1,46 +0,0 @@
////////////////////////////////////////////////////////////////////
//
// Unknown instructions
//
output header {{
/**
* Class for Unknown/Illegal instructions
*/
class Unknown : public SparcStaticInst
{
public:
// Constructor
Unknown(ExtMachInst _machInst) :
SparcStaticInst("unknown", _machInst, No_OpClass)
{
}
%(BasicExecDeclare)s
std::string generateDisassembly(Addr pc,
const SymbolTable *symtab) const;
};
}};
output decoder {{
std::string Unknown::generateDisassembly(Addr pc,
const SymbolTable *symtab) const
{
return "Unknown instruction";
}
}};
output exec {{
Fault Unknown::execute(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
return new IllegalInstruction;
}
}};
def format Unknown() {{
decode_block = 'return new Unknown(machInst);\n'
}};

View file

@ -1,46 +0,0 @@
////////////////////////////////////////////////////////////////////
//
// Output include file directives.
//
output header {{
#include <sstream>
#include <iostream>
#include <iomanip>
#include "cpu/static_inst.hh"
#include "arch/sparc/faults.hh"
#include "mem/request.hh" // some constructors use MemReq flags
#include "arch/sparc/isa_traits.hh"
#include "arch/sparc/regfile.hh"
}};
output decoder {{
#include "base/cprintf.hh"
#include "base/loader/symtab.hh"
#include "cpu/exec_context.hh" // for Jump::branchTarget()
#include <math.h>
#if defined(linux)
#include <fenv.h>
#endif
using namespace SparcISA;
}};
output exec {{
#include <math.h>
#if defined(linux)
#include <fenv.h>
#endif
#ifdef FULL_SYSTEM
//#include "sim/pseudo_inst.hh"
#endif
#include "cpu/base.hh"
#include "cpu/exetrace.hh"
#include "sim/sim_exit.hh"
using namespace SparcISA;
}};

28
ext/dnet/LICENSE Normal file
View file

@ -0,0 +1,28 @@
Copyright (c) 2000-2004 Dug Song <dugsong@monkey.org>
All rights reserved, all wrongs reversed.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The names of the authors and copyright holders may not be used to
endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

67
ext/dnet/dnet/addr.h Normal file
View file

@ -0,0 +1,67 @@
/*
* addr.h
*
* Network address operations.
*
* Copyright (c) 2000 Dug Song <dugsong@monkey.org>
*
* $Id: addr.h,v 1.12 2003/02/27 03:44:55 dugsong Exp $
*/
#ifndef DNET_ADDR_H
#define DNET_ADDR_H
#define ADDR_TYPE_NONE 0 /* No address set */
#define ADDR_TYPE_ETH 1 /* Ethernet */
#define ADDR_TYPE_IP 2 /* Internet Protocol v4 */
#define ADDR_TYPE_IP6 3 /* Internet Protocol v6 */
struct addr {
uint16_t addr_type;
uint16_t addr_bits;
union {
eth_addr_t __eth;
ip_addr_t __ip;
ip6_addr_t __ip6;
uint8_t __data8[16];
uint16_t __data16[8];
uint32_t __data32[4];
} __addr_u;
};
#define addr_eth __addr_u.__eth
#define addr_ip __addr_u.__ip
#define addr_ip6 __addr_u.__ip6
#define addr_data8 __addr_u.__data8
#define addr_data16 __addr_u.__data16
#define addr_data32 __addr_u.__data32
#define addr_pack(addr, type, bits, data, len) do { \
(addr)->addr_type = type; \
(addr)->addr_bits = bits; \
memmove((addr)->addr_data8, (char *)data, len); \
} while (0)
__BEGIN_DECLS
int addr_cmp(const struct addr *a, const struct addr *b);
int addr_bcast(const struct addr *a, struct addr *b);
int addr_net(const struct addr *a, struct addr *b);
char *addr_ntop(const struct addr *src, char *dst, size_t size);
int addr_pton(const char *src, struct addr *dst);
char *addr_ntoa(const struct addr *a);
#define addr_aton addr_pton
int addr_ntos(const struct addr *a, struct sockaddr *sa);
int addr_ston(const struct sockaddr *sa, struct addr *a);
int addr_btos(uint16_t bits, struct sockaddr *sa);
int addr_stob(const struct sockaddr *sa, uint16_t *bits);
int addr_btom(uint16_t bits, void *mask, size_t size);
int addr_mtob(const void *mask, size_t size, uint16_t *bits);
__END_DECLS
#endif /* DNET_ADDR_H */

103
ext/dnet/dnet/arp.h Normal file
View file

@ -0,0 +1,103 @@
/*
* arp.h
*
* Address Resolution Protocol.
* RFC 826
*
* Copyright (c) 2000 Dug Song <dugsong@monkey.org>
*
* $Id: arp.h,v 1.12 2003/03/16 17:39:17 dugsong Exp $
*/
#ifndef DNET_ARP_H
#define DNET_ARP_H
#define ARP_HDR_LEN 8 /* base ARP header length */
#define ARP_ETHIP_LEN 20 /* base ARP message length */
#ifndef __GNUC__
# define __attribute__(x)
# pragma pack(1)
#endif
/*
* ARP header
*/
struct arp_hdr {
uint16_t ar_hrd; /* format of hardware address */
uint16_t ar_pro; /* format of protocol address */
uint8_t ar_hln; /* length of hardware address (ETH_ADDR_LEN) */
uint8_t ar_pln; /* length of protocol address (IP_ADDR_LEN) */
uint16_t ar_op; /* operation */
};
/*
* Hardware address format
*/
#define ARP_HRD_ETH 0x0001 /* ethernet hardware */
#define ARP_HRD_IEEE802 0x0006 /* IEEE 802 hardware */
/*
* Protocol address format
*/
#define ARP_PRO_IP 0x0800 /* IP protocol */
/*
* ARP operation
*/
#define ARP_OP_REQUEST 1 /* request to resolve ha given pa */
#define ARP_OP_REPLY 2 /* response giving hardware address */
#define ARP_OP_REVREQUEST 3 /* request to resolve pa given ha */
#define ARP_OP_REVREPLY 4 /* response giving protocol address */
/*
* Ethernet/IP ARP message
*/
struct arp_ethip {
uint8_t ar_sha[ETH_ADDR_LEN]; /* sender hardware address */
uint8_t ar_spa[IP_ADDR_LEN]; /* sender protocol address */
uint8_t ar_tha[ETH_ADDR_LEN]; /* target hardware address */
uint8_t ar_tpa[IP_ADDR_LEN]; /* target protocol address */
};
/*
* ARP cache entry
*/
struct arp_entry {
struct addr arp_pa; /* protocol address */
struct addr arp_ha; /* hardware address */
};
#ifndef __GNUC__
# pragma pack()
#endif
#define arp_pack_hdr_ethip(hdr, op, sha, spa, tha, tpa) do { \
struct arp_hdr *pack_arp_p = (struct arp_hdr *)(hdr); \
struct arp_ethip *pack_ethip_p = (struct arp_ethip *) \
((uint8_t *)(hdr) + ARP_HDR_LEN); \
pack_arp_p->ar_hrd = htons(ARP_HRD_ETH); \
pack_arp_p->ar_pro = htons(ARP_PRO_IP); \
pack_arp_p->ar_hln = ETH_ADDR_LEN; \
pack_arp_p->ar_pln = IP_ADDR_LEN; \
pack_arp_p->ar_op = htons(op); \
memmove(pack_ethip_p->ar_sha, &(sha), ETH_ADDR_LEN); \
memmove(pack_ethip_p->ar_spa, &(spa), IP_ADDR_LEN); \
memmove(pack_ethip_p->ar_tha, &(tha), ETH_ADDR_LEN); \
memmove(pack_ethip_p->ar_tpa, &(tpa), IP_ADDR_LEN); \
} while (0)
typedef struct arp_handle arp_t;
typedef int (*arp_handler)(const struct arp_entry *entry, void *arg);
__BEGIN_DECLS
arp_t *arp_open(void);
int arp_add(arp_t *arp, const struct arp_entry *entry);
int arp_delete(arp_t *arp, const struct arp_entry *entry);
int arp_get(arp_t *arp, struct arp_entry *entry);
int arp_loop(arp_t *arp, arp_handler callback, void *arg);
arp_t *arp_close(arp_t *arp);
__END_DECLS
#endif /* DNET_ARP_H */

56
ext/dnet/dnet/blob.h Normal file
View file

@ -0,0 +1,56 @@
/*
* blob.h
*
* Binary blob handling.
*
* Copyright (c) 2002 Dug Song <dugsong@monkey.org>
*
* $Id: blob.h,v 1.2 2002/04/05 03:06:44 dugsong Exp $
*/
#ifndef DNET_BLOB_H
#define DNET_BLOB_H
typedef struct blob {
u_char *base; /* start of data */
int off; /* offset into data */
int end; /* end of data */
int size; /* size of allocation */
} blob_t;
__BEGIN_DECLS
blob_t *blob_new(void);
int blob_read(blob_t *b, void *buf, int len);
int blob_write(blob_t *b, const void *buf, int len);
int blob_seek(blob_t *b, int off, int whence);
#define blob_skip(b, l) blob_seek(b, l, SEEK_CUR)
#define blob_rewind(b) blob_seek(b, 0, SEEK_SET)
#define blob_offset(b) ((b)->off)
#define blob_left(b) ((b)->end - (b)->off)
int blob_index(blob_t *b, const void *buf, int len);
int blob_rindex(blob_t *b, const void *buf, int len);
int blob_pack(blob_t *b, const char *fmt, ...);
int blob_unpack(blob_t *b, const char *fmt, ...);
int blob_insert(blob_t *b, const void *buf, int len);
int blob_delete(blob_t *b, void *buf, int len);
int blob_print(blob_t *b, char *style, int len);
blob_t *blob_free(blob_t *b);
int blob_register_alloc(size_t size, void *(*bmalloc)(size_t),
void (*bfree)(void *), void *(*brealloc)(void *, size_t));
#ifdef va_start
typedef int (*blob_fmt_cb)(int pack, int len, blob_t *b, va_list *arg);
int blob_register_pack(char c, blob_fmt_cb fmt_cb);
#endif
__END_DECLS
#endif /* DNET_BLOB_H */

77
ext/dnet/dnet/eth.h Normal file
View file

@ -0,0 +1,77 @@
/*
* eth.h
*
* Ethernet.
*
* Copyright (c) 2000 Dug Song <dugsong@monkey.org>
*
* $Id: eth.h,v 1.15 2004/01/03 08:47:23 dugsong Exp $
*/
#ifndef DNET_ETH_H
#define DNET_ETH_H
#define ETH_ADDR_LEN 6
#define ETH_ADDR_BITS 48
#define ETH_TYPE_LEN 2
#define ETH_CRC_LEN 4
#define ETH_HDR_LEN 14
#define ETH_LEN_MIN 64 /* minimum frame length with CRC */
#define ETH_LEN_MAX 1518 /* maximum frame length with CRC */
#define ETH_MTU (ETH_LEN_MAX - ETH_HDR_LEN - ETH_CRC_LEN)
#define ETH_MIN (ETH_LEN_MIN - ETH_HDR_LEN - ETH_CRC_LEN)
typedef struct eth_addr {
uint8_t data[ETH_ADDR_LEN];
} eth_addr_t;
struct eth_hdr {
eth_addr_t eth_dst; /* destination address */
eth_addr_t eth_src; /* source address */
uint16_t eth_type; /* payload type */
};
/*
* Ethernet payload types - http://standards.ieee.org/regauth/ethertype
*/
#define ETH_TYPE_PUP 0x0200 /* PUP protocol */
#define ETH_TYPE_IP 0x0800 /* IP protocol */
#define ETH_TYPE_ARP 0x0806 /* address resolution protocol */
#define ETH_TYPE_REVARP 0x8035 /* reverse addr resolution protocol */
#define ETH_TYPE_8021Q 0x8100 /* IEEE 802.1Q VLAN tagging */
#define ETH_TYPE_IPV6 0x86DD /* IPv6 protocol */
#define ETH_TYPE_MPLS 0x8847 /* MPLS */
#define ETH_TYPE_MPLS_MCAST 0x8848 /* MPLS Multicast */
#define ETH_TYPE_PPPOEDISC 0x8863 /* PPP Over Ethernet Discovery Stage */
#define ETH_TYPE_PPPOE 0x8864 /* PPP Over Ethernet Session Stage */
#define ETH_TYPE_LOOPBACK 0x9000 /* used to test interfaces */
#define ETH_IS_MULTICAST(ea) (*(ea) & 0x01) /* is address mcast/bcast? */
#define ETH_ADDR_BROADCAST "\xff\xff\xff\xff\xff\xff"
#define eth_pack_hdr(h, dst, src, type) do { \
struct eth_hdr *eth_pack_p = (struct eth_hdr *)(h); \
memmove(&eth_pack_p->eth_dst, &(dst), ETH_ADDR_LEN); \
memmove(&eth_pack_p->eth_src, &(src), ETH_ADDR_LEN); \
eth_pack_p->eth_type = htons(type); \
} while (0)
typedef struct eth_handle eth_t;
__BEGIN_DECLS
eth_t *eth_open(const char *device);
int eth_get(eth_t *e, eth_addr_t *ea);
int eth_set(eth_t *e, const eth_addr_t *ea);
size_t eth_send(eth_t *e, const void *buf, size_t len);
eth_t *eth_close(eth_t *e);
char *eth_ntop(const eth_addr_t *eth, char *dst, size_t len);
int eth_pton(const char *src, eth_addr_t *dst);
char *eth_ntoa(const eth_addr_t *eth);
#define eth_aton eth_pton
__END_DECLS
#endif /* DNET_ETH_H */

54
ext/dnet/dnet/fw.h Normal file
View file

@ -0,0 +1,54 @@
/*
* fw.h
*
* Network firewalling operations.
*
* Copyright (c) 2001 Dug Song <dugsong@monkey.org>
*
* $Id: fw.h,v 1.13 2002/12/14 04:02:36 dugsong Exp $
*/
#ifndef DNET_FW_H
#define DNET_FW_H
struct fw_rule {
char fw_device[INTF_NAME_LEN]; /* interface name */
uint8_t fw_op; /* operation */
uint8_t fw_dir; /* direction */
uint8_t fw_proto; /* IP protocol */
struct addr fw_src; /* src address / net */
struct addr fw_dst; /* dst address / net */
uint16_t fw_sport[2]; /* range / ICMP type */
uint16_t fw_dport[2]; /* range / ICMP code */
};
#define FW_OP_ALLOW 1
#define FW_OP_BLOCK 2
#define FW_DIR_IN 1
#define FW_DIR_OUT 2
#define fw_pack_rule(rule, dev, op, dir, p, s, d, sp1, sp2, dp1, dp2) \
do { \
strlcpy((rule)->fw_device, dev, sizeof((rule)->fw_device)); \
(rule)->fw_op = op; (rule)->fw_dir = dir; \
(rule)->fw_proto = p; \
memmove(&(rule)->fw_src, &(s), sizeof((rule)->fw_src)); \
memmove(&(rule)->fw_dst, &(d), sizeof((rule)->fw_dst)); \
(rule)->fw_sport[0] = sp1; (rule)->fw_sport[1] = sp2; \
(rule)->fw_dport[0] = dp1; (rule)->fw_dport[1] = dp2; \
} while (0)
typedef struct fw_handle fw_t;
typedef int (*fw_handler)(const struct fw_rule *rule, void *arg);
__BEGIN_DECLS
fw_t *fw_open(void);
int fw_add(fw_t *f, const struct fw_rule *rule);
int fw_delete(fw_t *f, const struct fw_rule *rule);
int fw_loop(fw_t *f, fw_handler callback, void *arg);
fw_t *fw_close(fw_t *f);
__END_DECLS
#endif /* DNET_FW_H */

265
ext/dnet/dnet/icmp.h Normal file
View file

@ -0,0 +1,265 @@
/*
* icmp.h
*
* Internet Control Message Protocol.
* RFC 792, 950, 1256, 1393, 1475, 2002, 2521
*
* Copyright (c) 2000 Dug Song <dugsong@monkey.org>
*
* $Id: icmp.h,v 1.14 2003/03/16 17:39:17 dugsong Exp $
*/
#ifndef DNET_ICMP_H
#define DNET_ICMP_H
#define ICMP_HDR_LEN 4 /* base ICMP header length */
#define ICMP_LEN_MIN 8 /* minimum ICMP message size, with header */
#ifndef __GNUC__
# define __attribute__(x)
# pragma pack(1)
#endif
/*
* ICMP header
*/
struct icmp_hdr {
uint8_t icmp_type; /* type of message, see below */
uint8_t icmp_code; /* type sub code */
uint16_t icmp_cksum; /* ones complement cksum of struct */
};
/*
* Types (icmp_type) and codes (icmp_code) -
* http://www.iana.org/assignments/icmp-parameters
*/
#define ICMP_CODE_NONE 0 /* for types without codes */
#define ICMP_ECHOREPLY 0 /* echo reply */
#define ICMP_UNREACH 3 /* dest unreachable, codes: */
#define ICMP_UNREACH_NET 0 /* bad net */
#define ICMP_UNREACH_HOST 1 /* bad host */
#define ICMP_UNREACH_PROTO 2 /* bad protocol */
#define ICMP_UNREACH_PORT 3 /* bad port */
#define ICMP_UNREACH_NEEDFRAG 4 /* IP_DF caused drop */
#define ICMP_UNREACH_SRCFAIL 5 /* src route failed */
#define ICMP_UNREACH_NET_UNKNOWN 6 /* unknown net */
#define ICMP_UNREACH_HOST_UNKNOWN 7 /* unknown host */
#define ICMP_UNREACH_ISOLATED 8 /* src host isolated */
#define ICMP_UNREACH_NET_PROHIB 9 /* for crypto devs */
#define ICMP_UNREACH_HOST_PROHIB 10 /* ditto */
#define ICMP_UNREACH_TOSNET 11 /* bad tos for net */
#define ICMP_UNREACH_TOSHOST 12 /* bad tos for host */
#define ICMP_UNREACH_FILTER_PROHIB 13 /* prohibited access */
#define ICMP_UNREACH_HOST_PRECEDENCE 14 /* precedence error */
#define ICMP_UNREACH_PRECEDENCE_CUTOFF 15 /* precedence cutoff */
#define ICMP_SRCQUENCH 4 /* packet lost, slow down */
#define ICMP_REDIRECT 5 /* shorter route, codes: */
#define ICMP_REDIRECT_NET 0 /* for network */
#define ICMP_REDIRECT_HOST 1 /* for host */
#define ICMP_REDIRECT_TOSNET 2 /* for tos and net */
#define ICMP_REDIRECT_TOSHOST 3 /* for tos and host */
#define ICMP_ALTHOSTADDR 6 /* alternate host address */
#define ICMP_ECHO 8 /* echo service */
#define ICMP_RTRADVERT 9 /* router advertise, codes: */
#define ICMP_RTRADVERT_NORMAL 0 /* normal */
#define ICMP_RTRADVERT_NOROUTE_COMMON 16 /* selective routing */
#define ICMP_RTRSOLICIT 10 /* router solicitation */
#define ICMP_TIMEXCEED 11 /* time exceeded, code: */
#define ICMP_TIMEXCEED_INTRANS 0 /* ttl==0 in transit */
#define ICMP_TIMEXCEED_REASS 1 /* ttl==0 in reass */
#define ICMP_PARAMPROB 12 /* ip header bad */
#define ICMP_PARAMPROB_ERRATPTR 0 /* req. opt. absent */
#define ICMP_PARAMPROB_OPTABSENT 1 /* req. opt. absent */
#define ICMP_PARAMPROB_LENGTH 2 /* bad length */
#define ICMP_TSTAMP 13 /* timestamp request */
#define ICMP_TSTAMPREPLY 14 /* timestamp reply */
#define ICMP_INFO 15 /* information request */
#define ICMP_INFOREPLY 16 /* information reply */
#define ICMP_MASK 17 /* address mask request */
#define ICMP_MASKREPLY 18 /* address mask reply */
#define ICMP_TRACEROUTE 30 /* traceroute */
#define ICMP_DATACONVERR 31 /* data conversion error */
#define ICMP_MOBILE_REDIRECT 32 /* mobile host redirect */
#define ICMP_IPV6_WHEREAREYOU 33 /* IPv6 where-are-you */
#define ICMP_IPV6_IAMHERE 34 /* IPv6 i-am-here */
#define ICMP_MOBILE_REG 35 /* mobile registration req */
#define ICMP_MOBILE_REGREPLY 36 /* mobile registration reply */
#define ICMP_DNS 37 /* domain name request */
#define ICMP_DNSREPLY 38 /* domain name reply */
#define ICMP_SKIP 39 /* SKIP */
#define ICMP_PHOTURIS 40 /* Photuris */
#define ICMP_PHOTURIS_UNKNOWN_INDEX 0 /* unknown sec index */
#define ICMP_PHOTURIS_AUTH_FAILED 1 /* auth failed */
#define ICMP_PHOTURIS_DECOMPRESS_FAILED 2 /* decompress failed */
#define ICMP_PHOTURIS_DECRYPT_FAILED 3 /* decrypt failed */
#define ICMP_PHOTURIS_NEED_AUTHN 4 /* no authentication */
#define ICMP_PHOTURIS_NEED_AUTHZ 5 /* no authorization */
#define ICMP_TYPE_MAX 40
#define ICMP_INFOTYPE(type) \
((type) == ICMP_ECHOREPLY || (type) == ICMP_ECHO || \
(type) == ICMP_RTRADVERT || (type) == ICMP_RTRSOLICIT || \
(type) == ICMP_TSTAMP || (type) == ICMP_TSTAMPREPLY || \
(type) == ICMP_INFO || (type) == ICMP_INFOREPLY || \
(type) == ICMP_MASK || (type) == ICMP_MASKREPLY)
/*
* Echo message data
*/
struct icmp_msg_echo {
uint16_t icmp_id;
uint16_t icmp_seq;
uint8_t icmp_data __flexarr; /* optional data */
};
/*
* Fragmentation-needed (unreachable) message data
*/
struct icmp_msg_needfrag {
uint16_t icmp_void; /* must be zero */
uint16_t icmp_mtu; /* MTU of next-hop network */
uint8_t icmp_ip __flexarr; /* IP hdr + 8 bytes of pkt */
};
/*
* Unreachable, source quench, redirect, time exceeded,
* parameter problem message data
*/
struct icmp_msg_quote {
uint32_t icmp_void; /* must be zero */
#define icmp_gwaddr icmp_void /* router IP address to use */
#define icmp_pptr icmp_void /* ptr to bad octet field */
uint8_t icmp_ip __flexarr; /* IP hdr + 8 bytes of pkt */
};
/*
* Router advertisement message data, RFC 1256
*/
struct icmp_msg_rtradvert {
uint8_t icmp_num_addrs; /* # of address / pref pairs */
uint8_t icmp_wpa; /* words / address == 2 */
uint16_t icmp_lifetime; /* route lifetime in seconds */
struct icmp_msg_rtr_data {
uint32_t icmp_void;
#define icmp_gwaddr icmp_void /* router IP address */
uint32_t icmp_pref; /* router preference (usu 0) */
} icmp_rtr __flexarr; /* variable # of routers */
};
#define ICMP_RTR_PREF_NODEFAULT 0x80000000 /* do not use as default gw */
/*
* Timestamp message data
*/
struct icmp_msg_tstamp {
uint32_t icmp_id; /* identifier */
uint32_t icmp_seq; /* sequence number */
uint32_t icmp_ts_orig; /* originate timestamp */
uint32_t icmp_ts_rx; /* receive timestamp */
uint32_t icmp_ts_tx; /* transmit timestamp */
};
/*
* Address mask message data, RFC 950
*/
struct icmp_msg_mask {
uint32_t icmp_id; /* identifier */
uint32_t icmp_seq; /* sequence number */
uint32_t icmp_mask; /* address mask */
};
/*
* Traceroute message data, RFC 1393, RFC 1812
*/
struct icmp_msg_traceroute {
uint16_t icmp_id; /* identifier */
uint16_t icmp_void; /* unused */
uint16_t icmp_ohc; /* outbound hop count */
uint16_t icmp_rhc; /* return hop count */
uint32_t icmp_speed; /* link speed, bytes/sec */
uint32_t icmp_mtu; /* MTU in bytes */
};
/*
* Domain name reply message data, RFC 1788
*/
struct icmp_msg_dnsreply {
uint16_t icmp_id; /* identifier */
uint16_t icmp_seq; /* sequence number */
uint32_t icmp_ttl; /* time-to-live */
uint8_t icmp_names __flexarr; /* variable number of names */
};
/*
* Generic identifier, sequence number data
*/
struct icmp_msg_idseq {
uint16_t icmp_id;
uint16_t icmp_seq;
};
/*
* ICMP message union
*/
union icmp_msg {
struct icmp_msg_echo echo; /* ICMP_ECHO{REPLY} */
struct icmp_msg_quote unreach; /* ICMP_UNREACH */
struct icmp_msg_needfrag needfrag; /* ICMP_UNREACH_NEEDFRAG */
struct icmp_msg_quote srcquench; /* ICMP_SRCQUENCH */
struct icmp_msg_quote redirect; /* ICMP_REDIRECT (set to 0) */
uint32_t rtrsolicit; /* ICMP_RTRSOLICIT */
struct icmp_msg_rtradvert rtradvert; /* ICMP_RTRADVERT */
struct icmp_msg_quote timexceed; /* ICMP_TIMEXCEED */
struct icmp_msg_quote paramprob; /* ICMP_PARAMPROB */
struct icmp_msg_tstamp tstamp; /* ICMP_TSTAMP{REPLY} */
struct icmp_msg_idseq info; /* ICMP_INFO{REPLY} */
struct icmp_msg_mask mask; /* ICMP_MASK{REPLY} */
struct icmp_msg_traceroute traceroute; /* ICMP_TRACEROUTE */
struct icmp_msg_idseq dns; /* ICMP_DNS */
struct icmp_msg_dnsreply dnsreply; /* ICMP_DNSREPLY */
};
#ifndef __GNUC__
# pragma pack()
#endif
#define icmp_pack_hdr(hdr, type, code) do { \
struct icmp_hdr *icmp_pack_p = (struct icmp_hdr *)(hdr); \
icmp_pack_p->icmp_type = type; icmp_pack_p->icmp_code = code; \
} while (0)
#define icmp_pack_hdr_echo(hdr, type, code, id, seq, data, len) do { \
struct icmp_msg_echo *echo_pack_p = (struct icmp_msg_echo *) \
((uint8_t *)(hdr) + ICMP_HDR_LEN); \
icmp_pack_hdr(hdr, type, code); \
echo_pack_p->icmp_id = htons(id); \
echo_pack_p->icmp_seq = htons(seq); \
memmove(echo_pack_p->icmp_data, data, len); \
} while (0)
#define icmp_pack_hdr_quote(hdr, type, code, word, pkt, len) do { \
struct icmp_msg_quote *quote_pack_p = (struct icmp_msg_quote *) \
((uint8_t *)(hdr) + ICMP_HDR_LEN); \
icmp_pack_hdr(hdr, type, code); \
quote_pack_p->icmp_void = htonl(word); \
memmove(quote_pack_p->icmp_ip, pkt, len); \
} while (0)
#define icmp_pack_hdr_mask(hdr, type, code, id, seq, mask) do { \
struct icmp_msg_mask *mask_pack_p = (struct icmp_msg_mask *) \
((uint8_t *)(hdr) + ICMP_HDR_LEN); \
icmp_pack_hdr(hdr, type, code); \
mask_pack_p->icmp_id = htons(id); \
mask_pack_p->icmp_seq = htons(seq); \
mask_pack_p->icmp_mask = htonl(mask); \
} while (0)
#define icmp_pack_hdr_needfrag(hdr, type, code, mtu, pkt, len) do { \
struct icmp_msg_needfrag *frag_pack_p = \
(struct icmp_msg_needfrag *)((uint8_t *)(hdr) + ICMP_HDR_LEN); \
icmp_pack_hdr(hdr, type, code); \
frag_pack_p->icmp_void = 0; \
frag_pack_p->icmp_mtu = htons(mtu); \
memmove(frag_pack_p->icmp_ip, pkt, len); \
} while (0)
#endif /* DNET_ICMP_H */

68
ext/dnet/dnet/intf.h Normal file
View file

@ -0,0 +1,68 @@
/*
* intf.c
*
* Network interface operations.
*
* Copyright (c) 2000 Dug Song <dugsong@monkey.org>
*
* $Id: intf.h,v 1.16 2004/01/13 07:41:09 dugsong Exp $
*/
#ifndef DNET_INTF_H
#define DNET_INTF_H
/*
* Interface entry
*/
#define INTF_NAME_LEN 16
struct intf_entry {
u_int intf_len; /* length of entry */
char intf_name[INTF_NAME_LEN]; /* interface name */
u_short intf_type; /* interface type (r/o) */
u_short intf_flags; /* interface flags */
u_int intf_mtu; /* interface MTU */
struct addr intf_addr; /* interface address */
struct addr intf_dst_addr; /* point-to-point dst */
struct addr intf_link_addr; /* link-layer address */
u_int intf_alias_num; /* number of aliases */
struct addr intf_alias_addrs __flexarr; /* array of aliases */
};
/*
* MIB-II interface types - http://www.iana.org/assignments/ianaiftype-mib
*/
#define INTF_TYPE_OTHER 1 /* other */
#define INTF_TYPE_ETH 6 /* Ethernet */
#define INTF_TYPE_TOKENRING 9 /* Token Ring */
#define INTF_TYPE_FDDI 15 /* FDDI */
#define INTF_TYPE_PPP 23 /* Point-to-Point Protocol */
#define INTF_TYPE_LOOPBACK 24 /* software loopback */
#define INTF_TYPE_SLIP 28 /* Serial Line Interface Protocol */
#define INTF_TYPE_TUN 53 /* proprietary virtual/internal */
/*
* Interface flags
*/
#define INTF_FLAG_UP 0x01 /* enable interface */
#define INTF_FLAG_LOOPBACK 0x02 /* is a loopback net (r/o) */
#define INTF_FLAG_POINTOPOINT 0x04 /* point-to-point link (r/o) */
#define INTF_FLAG_NOARP 0x08 /* disable ARP */
#define INTF_FLAG_BROADCAST 0x10 /* supports broadcast (r/o) */
#define INTF_FLAG_MULTICAST 0x20 /* supports multicast (r/o) */
typedef struct intf_handle intf_t;
typedef int (*intf_handler)(const struct intf_entry *entry, void *arg);
__BEGIN_DECLS
intf_t *intf_open(void);
int intf_get(intf_t *i, struct intf_entry *entry);
int intf_get_src(intf_t *i, struct intf_entry *entry, struct addr *src);
int intf_get_dst(intf_t *i, struct intf_entry *entry, struct addr *dst);
int intf_set(intf_t *i, const struct intf_entry *entry);
int intf_loop(intf_t *i, intf_handler callback, void *arg);
intf_t *intf_close(intf_t *i);
__END_DECLS
#endif /* DNET_INTF_H */

487
ext/dnet/dnet/ip.h Normal file
View file

@ -0,0 +1,487 @@
/*
* ip.h
*
* Internet Protocol (RFC 791).
*
* Copyright (c) 2000 Dug Song <dugsong@monkey.org>
*
* $Id: ip.h,v 1.23 2003/03/16 17:39:17 dugsong Exp $
*/
#ifndef DNET_IP_H
#define DNET_IP_H
#define IP_ADDR_LEN 4 /* IP address length */
#define IP_ADDR_BITS 32 /* IP address bits */
#define IP_HDR_LEN 20 /* base IP header length */
#define IP_OPT_LEN 2 /* base IP option length */
#define IP_OPT_LEN_MAX 40
#define IP_HDR_LEN_MAX (IP_HDR_LEN + IP_OPT_LEN_MAX)
#define IP_LEN_MAX 65535
#define IP_LEN_MIN IP_HDR_LEN
typedef uint32_t ip_addr_t;
#ifndef __GNUC__
# define __attribute__(x)
# pragma pack(1)
#endif
/*
* IP header, without options
*/
struct ip_hdr {
#if DNET_BYTESEX == DNET_BIG_ENDIAN
uint8_t ip_v:4, /* version */
ip_hl:4; /* header length (incl any options) */
#elif DNET_BYTESEX == DNET_LIL_ENDIAN
uint8_t ip_hl:4,
ip_v:4;
#else
# error "need to include <dnet.h>"
#endif
uint8_t ip_tos; /* type of service */
uint16_t ip_len; /* total length (incl header) */
uint16_t ip_id; /* identification */
uint16_t ip_off; /* fragment offset and flags */
uint8_t ip_ttl; /* time to live */
uint8_t ip_p; /* protocol */
uint16_t ip_sum; /* checksum */
ip_addr_t ip_src; /* source address */
ip_addr_t ip_dst; /* destination address */
};
/*
* Type of service (ip_tos), RFC 1349 ("obsoleted by RFC 2474")
*/
#define IP_TOS_DEFAULT 0x00 /* default */
#define IP_TOS_LOWDELAY 0x10 /* low delay */
#define IP_TOS_THROUGHPUT 0x08 /* high throughput */
#define IP_TOS_RELIABILITY 0x04 /* high reliability */
#define IP_TOS_LOWCOST 0x02 /* low monetary cost - XXX */
#define IP_TOS_ECT 0x02 /* ECN-capable transport */
#define IP_TOS_CE 0x01 /* congestion experienced */
/*
* IP precedence (high 3 bits of ip_tos), hopefully unused
*/
#define IP_TOS_PREC_ROUTINE 0x00
#define IP_TOS_PREC_PRIORITY 0x20
#define IP_TOS_PREC_IMMEDIATE 0x40
#define IP_TOS_PREC_FLASH 0x60
#define IP_TOS_PREC_FLASHOVERRIDE 0x80
#define IP_TOS_PREC_CRITIC_ECP 0xa0
#define IP_TOS_PREC_INTERNETCONTROL 0xc0
#define IP_TOS_PREC_NETCONTROL 0xe0
/*
* Fragmentation flags (ip_off)
*/
#define IP_RF 0x8000 /* reserved */
#define IP_DF 0x4000 /* don't fragment */
#define IP_MF 0x2000 /* more fragments (not last frag) */
#define IP_OFFMASK 0x1fff /* mask for fragment offset */
/*
* Time-to-live (ip_ttl), seconds
*/
#define IP_TTL_DEFAULT 64 /* default ttl, RFC 1122, RFC 1340 */
#define IP_TTL_MAX 255 /* maximum ttl */
/*
* Protocol (ip_p) - http://www.iana.org/assignments/protocol-numbers
*/
#define IP_PROTO_IP 0 /* dummy for IP */
#define IP_PROTO_HOPOPTS IP_PROTO_IP /* IPv6 hop-by-hop options */
#define IP_PROTO_ICMP 1 /* ICMP */
#define IP_PROTO_IGMP 2 /* IGMP */
#define IP_PROTO_GGP 3 /* gateway-gateway protocol */
#define IP_PROTO_IPIP 4 /* IP in IP */
#define IP_PROTO_ST 5 /* ST datagram mode */
#define IP_PROTO_TCP 6 /* TCP */
#define IP_PROTO_CBT 7 /* CBT */
#define IP_PROTO_EGP 8 /* exterior gateway protocol */
#define IP_PROTO_IGP 9 /* interior gateway protocol */
#define IP_PROTO_BBNRCC 10 /* BBN RCC monitoring */
#define IP_PROTO_NVP 11 /* Network Voice Protocol */
#define IP_PROTO_PUP 12 /* PARC universal packet */
#define IP_PROTO_ARGUS 13 /* ARGUS */
#define IP_PROTO_EMCON 14 /* EMCON */
#define IP_PROTO_XNET 15 /* Cross Net Debugger */
#define IP_PROTO_CHAOS 16 /* Chaos */
#define IP_PROTO_UDP 17 /* UDP */
#define IP_PROTO_MUX 18 /* multiplexing */
#define IP_PROTO_DCNMEAS 19 /* DCN measurement */
#define IP_PROTO_HMP 20 /* Host Monitoring Protocol */
#define IP_PROTO_PRM 21 /* Packet Radio Measurement */
#define IP_PROTO_IDP 22 /* Xerox NS IDP */
#define IP_PROTO_TRUNK1 23 /* Trunk-1 */
#define IP_PROTO_TRUNK2 24 /* Trunk-2 */
#define IP_PROTO_LEAF1 25 /* Leaf-1 */
#define IP_PROTO_LEAF2 26 /* Leaf-2 */
#define IP_PROTO_RDP 27 /* "Reliable Datagram" proto */
#define IP_PROTO_IRTP 28 /* Inet Reliable Transaction */
#define IP_PROTO_TP 29 /* ISO TP class 4 */
#define IP_PROTO_NETBLT 30 /* Bulk Data Transfer */
#define IP_PROTO_MFPNSP 31 /* MFE Network Services */
#define IP_PROTO_MERITINP 32 /* Merit Internodal Protocol */
#define IP_PROTO_SEP 33 /* Sequential Exchange proto */
#define IP_PROTO_3PC 34 /* Third Party Connect proto */
#define IP_PROTO_IDPR 35 /* Interdomain Policy Route */
#define IP_PROTO_XTP 36 /* Xpress Transfer Protocol */
#define IP_PROTO_DDP 37 /* Datagram Delivery Proto */
#define IP_PROTO_CMTP 38 /* IDPR Ctrl Message Trans */
#define IP_PROTO_TPPP 39 /* TP++ Transport Protocol */
#define IP_PROTO_IL 40 /* IL Transport Protocol */
#define IP_PROTO_IPV6 41 /* IPv6 */
#define IP_PROTO_SDRP 42 /* Source Demand Routing */
#define IP_PROTO_ROUTING 43 /* IPv6 routing header */
#define IP_PROTO_FRAGMENT 44 /* IPv6 fragmentation header */
#define IP_PROTO_RSVP 46 /* Reservation protocol */
#define IP_PROTO_GRE 47 /* General Routing Encap */
#define IP_PROTO_MHRP 48 /* Mobile Host Routing */
#define IP_PROTO_ENA 49 /* ENA */
#define IP_PROTO_ESP 50 /* Encap Security Payload */
#define IP_PROTO_AH 51 /* Authentication Header */
#define IP_PROTO_INLSP 52 /* Integated Net Layer Sec */
#define IP_PROTO_SWIPE 53 /* SWIPE */
#define IP_PROTO_NARP 54 /* NBMA Address Resolution */
#define IP_PROTO_MOBILE 55 /* Mobile IP, RFC 2004 */
#define IP_PROTO_TLSP 56 /* Transport Layer Security */
#define IP_PROTO_SKIP 57 /* SKIP */
#define IP_PROTO_ICMPV6 58 /* ICMP for IPv6 */
#define IP_PROTO_NONE 59 /* IPv6 no next header */
#define IP_PROTO_DSTOPTS 60 /* IPv6 destination options */
#define IP_PROTO_ANYHOST 61 /* any host internal proto */
#define IP_PROTO_CFTP 62 /* CFTP */
#define IP_PROTO_ANYNET 63 /* any local network */
#define IP_PROTO_EXPAK 64 /* SATNET and Backroom EXPAK */
#define IP_PROTO_KRYPTOLAN 65 /* Kryptolan */
#define IP_PROTO_RVD 66 /* MIT Remote Virtual Disk */
#define IP_PROTO_IPPC 67 /* Inet Pluribus Packet Core */
#define IP_PROTO_DISTFS 68 /* any distributed fs */
#define IP_PROTO_SATMON 69 /* SATNET Monitoring */
#define IP_PROTO_VISA 70 /* VISA Protocol */
#define IP_PROTO_IPCV 71 /* Inet Packet Core Utility */
#define IP_PROTO_CPNX 72 /* Comp Proto Net Executive */
#define IP_PROTO_CPHB 73 /* Comp Protocol Heart Beat */
#define IP_PROTO_WSN 74 /* Wang Span Network */
#define IP_PROTO_PVP 75 /* Packet Video Protocol */
#define IP_PROTO_BRSATMON 76 /* Backroom SATNET Monitor */
#define IP_PROTO_SUNND 77 /* SUN ND Protocol */
#define IP_PROTO_WBMON 78 /* WIDEBAND Monitoring */
#define IP_PROTO_WBEXPAK 79 /* WIDEBAND EXPAK */
#define IP_PROTO_EON 80 /* ISO CNLP */
#define IP_PROTO_VMTP 81 /* Versatile Msg Transport*/
#define IP_PROTO_SVMTP 82 /* Secure VMTP */
#define IP_PROTO_VINES 83 /* VINES */
#define IP_PROTO_TTP 84 /* TTP */
#define IP_PROTO_NSFIGP 85 /* NSFNET-IGP */
#define IP_PROTO_DGP 86 /* Dissimilar Gateway Proto */
#define IP_PROTO_TCF 87 /* TCF */
#define IP_PROTO_EIGRP 88 /* EIGRP */
#define IP_PROTO_OSPF 89 /* Open Shortest Path First */
#define IP_PROTO_SPRITERPC 90 /* Sprite RPC Protocol */
#define IP_PROTO_LARP 91 /* Locus Address Resolution */
#define IP_PROTO_MTP 92 /* Multicast Transport Proto */
#define IP_PROTO_AX25 93 /* AX.25 Frames */
#define IP_PROTO_IPIPENCAP 94 /* yet-another IP encap */
#define IP_PROTO_MICP 95 /* Mobile Internet Ctrl */
#define IP_PROTO_SCCSP 96 /* Semaphore Comm Sec Proto */
#define IP_PROTO_ETHERIP 97 /* Ethernet in IPv4 */
#define IP_PROTO_ENCAP 98 /* encapsulation header */
#define IP_PROTO_ANYENC 99 /* private encryption scheme */
#define IP_PROTO_GMTP 100 /* GMTP */
#define IP_PROTO_IFMP 101 /* Ipsilon Flow Mgmt Proto */
#define IP_PROTO_PNNI 102 /* PNNI over IP */
#define IP_PROTO_PIM 103 /* Protocol Indep Multicast */
#define IP_PROTO_ARIS 104 /* ARIS */
#define IP_PROTO_SCPS 105 /* SCPS */
#define IP_PROTO_QNX 106 /* QNX */
#define IP_PROTO_AN 107 /* Active Networks */
#define IP_PROTO_IPCOMP 108 /* IP Payload Compression */
#define IP_PROTO_SNP 109 /* Sitara Networks Protocol */
#define IP_PROTO_COMPAQPEER 110 /* Compaq Peer Protocol */
#define IP_PROTO_IPXIP 111 /* IPX in IP */
#define IP_PROTO_VRRP 112 /* Virtual Router Redundancy */
#define IP_PROTO_PGM 113 /* PGM Reliable Transport */
#define IP_PROTO_ANY0HOP 114 /* 0-hop protocol */
#define IP_PROTO_L2TP 115 /* Layer 2 Tunneling Proto */
#define IP_PROTO_DDX 116 /* D-II Data Exchange (DDX) */
#define IP_PROTO_IATP 117 /* Interactive Agent Xfer */
#define IP_PROTO_STP 118 /* Schedule Transfer Proto */
#define IP_PROTO_SRP 119 /* SpectraLink Radio Proto */
#define IP_PROTO_UTI 120 /* UTI */
#define IP_PROTO_SMP 121 /* Simple Message Protocol */
#define IP_PROTO_SM 122 /* SM */
#define IP_PROTO_PTP 123 /* Performance Transparency */
#define IP_PROTO_ISIS 124 /* ISIS over IPv4 */
#define IP_PROTO_FIRE 125 /* FIRE */
#define IP_PROTO_CRTP 126 /* Combat Radio Transport */
#define IP_PROTO_CRUDP 127 /* Combat Radio UDP */
#define IP_PROTO_SSCOPMCE 128 /* SSCOPMCE */
#define IP_PROTO_IPLT 129 /* IPLT */
#define IP_PROTO_SPS 130 /* Secure Packet Shield */
#define IP_PROTO_PIPE 131 /* Private IP Encap in IP */
#define IP_PROTO_SCTP 132 /* Stream Ctrl Transmission */
#define IP_PROTO_FC 133 /* Fibre Channel */
#define IP_PROTO_RSVPIGN 134 /* RSVP-E2E-IGNORE */
#define IP_PROTO_RAW 255 /* Raw IP packets */
#define IP_PROTO_RESERVED IP_PROTO_RAW /* Reserved */
#define IP_PROTO_MAX 255
/*
* Option types (opt_type) - http://www.iana.org/assignments/ip-parameters
*/
#define IP_OPT_CONTROL 0x00 /* control */
#define IP_OPT_DEBMEAS 0x40 /* debugging & measurement */
#define IP_OPT_COPY 0x80 /* copy into all fragments */
#define IP_OPT_RESERVED1 0x20
#define IP_OPT_RESERVED2 0x60
#define IP_OPT_EOL 0 /* end of option list */
#define IP_OPT_NOP 1 /* no operation */
#define IP_OPT_SEC (2|IP_OPT_COPY) /* DoD basic security */
#define IP_OPT_LSRR (3|IP_OPT_COPY) /* loose source route */
#define IP_OPT_TS (4|IP_OPT_DEBMEAS) /* timestamp */
#define IP_OPT_ESEC (5|IP_OPT_COPY) /* DoD extended security */
#define IP_OPT_CIPSO (6|IP_OPT_COPY) /* commercial security */
#define IP_OPT_RR 7 /* record route */
#define IP_OPT_SATID (8|IP_OPT_COPY) /* stream ID (obsolete) */
#define IP_OPT_SSRR (9|IP_OPT_COPY) /* strict source route */
#define IP_OPT_ZSU 10 /* experimental measurement */
#define IP_OPT_MTUP 11 /* MTU probe */
#define IP_OPT_MTUR 12 /* MTU reply */
#define IP_OPT_FINN (13|IP_OPT_COPY|IP_OPT_DEBMEAS) /* exp flow control */
#define IP_OPT_VISA (14|IP_OPT_COPY) /* exp access control */
#define IP_OPT_ENCODE 15 /* ??? */
#define IP_OPT_IMITD (16|IP_OPT_COPY) /* IMI traffic descriptor */
#define IP_OPT_EIP (17|IP_OPT_COPY) /* extended IP, RFC 1385 */
#define IP_OPT_TR (18|IP_OPT_DEBMEAS) /* traceroute */
#define IP_OPT_ADDEXT (19|IP_OPT_COPY) /* IPv7 ext addr, RFC 1475 */
#define IP_OPT_RTRALT (20|IP_OPT_COPY) /* router alert, RFC 2113 */
#define IP_OPT_SDB (21|IP_OPT_COPY) /* directed bcast, RFC 1770 */
#define IP_OPT_NSAPA (22|IP_OPT_COPY) /* NSAP addresses */
#define IP_OPT_DPS (23|IP_OPT_COPY) /* dynamic packet state */
#define IP_OPT_UMP (24|IP_OPT_COPY) /* upstream multicast */
#define IP_OPT_MAX 25
#define IP_OPT_COPIED(o) ((o) & 0x80)
#define IP_OPT_CLASS(o) ((o) & 0x60)
#define IP_OPT_NUMBER(o) ((o) & 0x1f)
#define IP_OPT_TYPEONLY(o) ((o) == IP_OPT_EOL || (o) == IP_OPT_NOP)
/*
* Security option data - RFC 791, 3.1
*/
struct ip_opt_data_sec {
uint16_t s; /* security */
uint16_t c; /* compartments */
uint16_t h; /* handling restrictions */
uint8_t tcc[3]; /* transmission control code */
} __attribute__((__packed__));
#define IP_OPT_SEC_UNCLASS 0x0000 /* unclassified */
#define IP_OPT_SEC_CONFID 0xf135 /* confidential */
#define IP_OPT_SEC_EFTO 0x789a /* EFTO */
#define IP_OPT_SEC_MMMM 0xbc4d /* MMMM */
#define IP_OPT_SEC_PROG 0x5e26 /* PROG */
#define IP_OPT_SEC_RESTR 0xaf13 /* restricted */
#define IP_OPT_SEC_SECRET 0xd788 /* secret */
#define IP_OPT_SEC_TOPSECRET 0x6bc5 /* top secret */
/*
* {Loose Source, Record, Strict Source} Route option data - RFC 791, 3.1
*/
struct ip_opt_data_rr {
uint8_t ptr; /* from start of option, >= 4 */
uint32_t iplist __flexarr; /* list of IP addresses */
} __attribute__((__packed__));
/*
* Timestamp option data - RFC 791, 3.1
*/
struct ip_opt_data_ts {
uint8_t ptr; /* from start of option, >= 5 */
#if DNET_BYTESEX == DNET_BIG_ENDIAN
uint8_t oflw:4, /* number of IPs skipped */
flg:4; /* address[ / timestamp] flag */
#elif DNET_BYTESEX == DNET_LIL_ENDIAN
uint8_t flg:4,
oflw:4;
#endif
uint32_t ipts __flexarr; /* IP address [/ timestamp] pairs */
} __attribute__((__packed__));
#define IP_OPT_TS_TSONLY 0 /* timestamps only */
#define IP_OPT_TS_TSADDR 1 /* IP address / timestamp pairs */
#define IP_OPT_TS_PRESPEC 3 /* IP address / zero timestamp pairs */
/*
* Traceroute option data - RFC 1393, 2.2
*/
struct ip_opt_data_tr {
uint16_t id; /* ID number */
uint16_t ohc; /* outbound hop count */
uint16_t rhc; /* return hop count */
uint32_t origip; /* originator IP address */
} __attribute__((__packed__));
/*
* IP option (following IP header)
*/
struct ip_opt {
uint8_t opt_type; /* option type */
uint8_t opt_len; /* option length >= IP_OPT_LEN */
union ip_opt_data {
struct ip_opt_data_sec sec; /* IP_OPT_SEC */
struct ip_opt_data_rr rr; /* IP_OPT_{L,S}RR */
struct ip_opt_data_ts ts; /* IP_OPT_TS */
uint16_t satid; /* IP_OPT_SATID */
uint16_t mtu; /* IP_OPT_MTU{P,R} */
struct ip_opt_data_tr tr; /* IP_OPT_TR */
uint32_t addext[2]; /* IP_OPT_ADDEXT */
uint16_t rtralt; /* IP_OPT_RTRALT */
uint32_t sdb[9]; /* IP_OPT_SDB */
uint8_t data8[IP_OPT_LEN_MAX - IP_OPT_LEN];
} opt_data;
} __attribute__((__packed__));
#ifndef __GNUC__
# pragma pack()
#endif
/*
* Classful addressing
*/
#define IP_CLASSA(i) (((uint32_t)(i) & htonl(0x80000000)) == \
htonl(0x00000000))
#define IP_CLASSA_NET (htonl(0xff000000))
#define IP_CLASSA_NSHIFT 24
#define IP_CLASSA_HOST (htonl(0x00ffffff))
#define IP_CLASSA_MAX 128
#define IP_CLASSB(i) (((uint32_t)(i) & htonl(0xc0000000)) == \
htonl(0x80000000))
#define IP_CLASSB_NET (htonl(0xffff0000))
#define IP_CLASSB_NSHIFT 16
#define IP_CLASSB_HOST (htonl(0x0000ffff))
#define IP_CLASSB_MAX 65536
#define IP_CLASSC(i) (((uint32_t)(i) & htonl(0xe0000000)) == \
htonl(0xc0000000))
#define IP_CLASSC_NET (htonl(0xffffff00))
#define IP_CLASSC_NSHIFT 8
#define IP_CLASSC_HOST (htonl(0x000000ff))
#define IP_CLASSD(i) (((uint32_t)(i) & htonl(0xf0000000)) == \
htonl(0xe0000000))
/* These ones aren't really net and host fields, but routing needn't know. */
#define IP_CLASSD_NET (htonl(0xf0000000))
#define IP_CLASSD_NSHIFT 28
#define IP_CLASSD_HOST (htonl(0x0fffffff))
#define IP_MULTICAST(i) IP_CLASSD(i)
#define IP_EXPERIMENTAL(i) (((uint32_t)(i) & htonl(0xf0000000)) == \
htonl(0xf0000000))
#define IP_BADCLASS(i) (((uint32_t)(i) & htonl(0xf0000000)) == \
htonl(0xf0000000))
#define IP_LOCAL_GROUP(i) (((uint32_t)(i) & htonl(0xffffff00)) == \
htonl(0xe0000000))
/*
* Reserved addresses
*/
#define IP_ADDR_ANY (htonl(0x00000000)) /* 0.0.0.0 */
#define IP_ADDR_BROADCAST (htonl(0xffffffff)) /* 255.255.255.255 */
#define IP_ADDR_LOOPBACK (htonl(0x7f000001)) /* 127.0.0.1 */
#define IP_ADDR_MCAST_ALL (htonl(0xe0000001)) /* 224.0.0.1 */
#define IP_ADDR_MCAST_LOCAL (htonl(0xe00000ff)) /* 224.0.0.225 */
#define ip_pack_hdr(hdr, tos, len, id, off, ttl, p, src, dst) do { \
struct ip_hdr *ip_pack_p = (struct ip_hdr *)(hdr); \
ip_pack_p->ip_v = 4; ip_pack_p->ip_hl = 5; \
ip_pack_p->ip_tos = tos; ip_pack_p->ip_len = htons(len); \
ip_pack_p->ip_id = htons(id); ip_pack_p->ip_off = htons(off); \
ip_pack_p->ip_ttl = ttl; ip_pack_p->ip_p = p; \
ip_pack_p->ip_src = src; ip_pack_p->ip_dst = dst; \
} while (0)
typedef struct ip_handle ip_t;
__BEGIN_DECLS
ip_t *ip_open(void);
size_t ip_send(ip_t *i, const void *buf, size_t len);
ip_t *ip_close(ip_t *i);
char *ip_ntop(const ip_addr_t *ip, char *dst, size_t len);
int ip_pton(const char *src, ip_addr_t *dst);
char *ip_ntoa(const ip_addr_t *ip);
#define ip_aton ip_pton
size_t ip_add_option(void *buf, size_t len,
int proto, const void *optbuf, size_t optlen);
void ip_checksum(void *buf, size_t len);
inline int
ip_cksum_add(const void *buf, size_t len, int cksum)
{
uint16_t *sp = (uint16_t *)buf;
int n, sn;
sn = len / 2;
n = (sn + 15) / 16;
/* XXX - unroll loop using Duff's device. */
switch (sn % 16) {
case 0: do {
cksum += *sp++;
case 15:
cksum += *sp++;
case 14:
cksum += *sp++;
case 13:
cksum += *sp++;
case 12:
cksum += *sp++;
case 11:
cksum += *sp++;
case 10:
cksum += *sp++;
case 9:
cksum += *sp++;
case 8:
cksum += *sp++;
case 7:
cksum += *sp++;
case 6:
cksum += *sp++;
case 5:
cksum += *sp++;
case 4:
cksum += *sp++;
case 3:
cksum += *sp++;
case 2:
cksum += *sp++;
case 1:
cksum += *sp++;
} while (--n > 0);
}
if (len & 1)
cksum += htons(*(u_char *)sp << 8);
return (cksum);
}
inline uint16_t
ip_cksum_carry(int x)
{
x = (x >> 16) + (x & 0xffff);
return ~(x + (x >> 16)) & 0xffff;
}
__END_DECLS
#endif /* DNET_IP_H */

183
ext/dnet/dnet/ip6.h Normal file
View file

@ -0,0 +1,183 @@
/*
* ip6.h
*
* Internet Protocol, Version 6 (RFC 2460).
*
* Copyright (c) 2002 Dug Song <dugsong@monkey.org>
*
* $Id: ip6.h,v 1.6 2004/02/23 10:01:15 dugsong Exp $
*/
#ifndef DNET_IP6_H
#define DNET_IP6_H
#define IP6_ADDR_LEN 16
#define IP6_ADDR_BITS 128
#define IP6_HDR_LEN 40 /* IPv6 header length */
#define IP6_LEN_MIN IP6_HDR_LEN
#define IP6_LEN_MAX 65535 /* non-jumbo payload */
#define IP6_MTU_MIN 1280 /* minimum MTU (1024 + 256) */
typedef struct ip6_addr {
uint8_t data[IP6_ADDR_LEN];
} ip6_addr_t;
#ifndef __GNUC__
# define __attribute__(x)
# pragma pack(1)
#endif
/*
* IPv6 header
*/
struct ip6_hdr {
union {
struct ip6_hdr_ctl {
uint32_t ip6_un1_flow; /* 20 bits of flow ID */
uint16_t ip6_un1_plen; /* payload length */
uint8_t ip6_un1_nxt; /* next header */
uint8_t ip6_un1_hlim; /* hop limit */
} ip6_un1;
uint8_t ip6_un2_vfc; /* 4 bits version, top 4 bits class */
} ip6_ctlun;
ip6_addr_t ip6_src;
ip6_addr_t ip6_dst;
} __attribute__((__packed__));
#define ip6_vfc ip6_ctlun.ip6_un2_vfc
#define ip6_flow ip6_ctlun.ip6_un1.ip6_un1_flow
#define ip6_plen ip6_ctlun.ip6_un1.ip6_un1_plen
#define ip6_nxt ip6_ctlun.ip6_un1.ip6_un1_nxt /* IP_PROTO_* */
#define ip6_hlim ip6_ctlun.ip6_un1.ip6_un1_hlim
#define IP6_VERSION 0x60
#define IP6_VERSION_MASK 0xf0 /* ip6_vfc version */
#if DNET_BYTESEX == DNET_BIG_ENDIAN
#define IP6_FLOWINFO_MASK 0x0fffffff /* ip6_flow info (28 bits) */
#define IP6_FLOWLABEL_MASK 0x000fffff /* ip6_flow label (20 bits) */
#elif DNET_BYTESEX == DNET_LIL_ENDIAN
#define IP6_FLOWINFO_MASK 0xffffff0f /* ip6_flow info (28 bits) */
#define IP6_FLOWLABEL_MASK 0xffff0f00 /* ip6_flow label (20 bits) */
#endif
/*
* Hop limit (ip6_hlim)
*/
#define IP6_HLIM_DEFAULT 64
#define IP6_HLIM_MAX 255
/*
* Preferred extension header order from RFC 2460, 4.1:
*
* IP_PROTO_IPV6, IP_PROTO_HOPOPTS, IP_PROTO_DSTOPTS, IP_PROTO_ROUTING,
* IP_PROTO_FRAGMENT, IP_PROTO_AH, IP_PROTO_ESP, IP_PROTO_DSTOPTS, IP_PROTO_*
*/
/*
* Routing header data (IP_PROTO_ROUTING)
*/
struct ip6_ext_data_routing {
uint8_t type; /* routing type */
uint8_t segleft; /* segments left */
/* followed by routing type specific data */
} __attribute__((__packed__));
struct ip6_ext_data_routing0 {
uint8_t type; /* always zero */
uint8_t segleft; /* segments left */
uint8_t reserved; /* reserved field */
uint8_t slmap[3]; /* strict/loose bit map */
ip6_addr_t addr[1]; /* up to 23 addresses */
} __attribute__((__packed__));
/*
* Fragment header data (IP_PROTO_FRAGMENT)
*/
struct ip6_ext_data_fragment {
uint16_t offlg; /* offset, reserved, and flag */
uint32_t ident; /* identification */
} __attribute__((__packed__));
/*
* Fragmentation offset, reserved, and flags (offlg)
*/
#if DNET_BYTESEX == DNET_BIG_ENDIAN
#define IP6_OFF_MASK 0xfff8 /* mask out offset from offlg */
#define IP6_RESERVED_MASK 0x0006 /* reserved bits in offlg */
#define IP6_MORE_FRAG 0x0001 /* more-fragments flag */
#elif DNET_BYTESEX == DNET_LIL_ENDIAN
#define IP6_OFF_MASK 0xf8ff /* mask out offset from offlg */
#define IP6_RESERVED_MASK 0x0600 /* reserved bits in offlg */
#define IP6_MORE_FRAG 0x0100 /* more-fragments flag */
#endif
/*
* Option types, for IP_PROTO_HOPOPTS, IP_PROTO_DSTOPTS headers
*/
#define IP6_OPT_PAD1 0x00 /* 00 0 00000 */
#define IP6_OPT_PADN 0x01 /* 00 0 00001 */
#define IP6_OPT_JUMBO 0xC2 /* 11 0 00010 = 194 */
#define IP6_OPT_JUMBO_LEN 6
#define IP6_OPT_RTALERT 0x05 /* 00 0 00101 */
#define IP6_OPT_RTALERT_LEN 4
#define IP6_OPT_RTALERT_MLD 0 /* Datagram contains an MLD message */
#define IP6_OPT_RTALERT_RSVP 1 /* Datagram contains an RSVP message */
#define IP6_OPT_RTALERT_ACTNET 2 /* contains an Active Networks msg */
#define IP6_OPT_LEN_MIN 2
#define IP6_OPT_TYPE(o) ((o) & 0xC0) /* high 2 bits of opt_type */
#define IP6_OPT_TYPE_SKIP 0x00 /* continue processing on failure */
#define IP6_OPT_TYPE_DISCARD 0x40 /* discard packet on failure */
#define IP6_OPT_TYPE_FORCEICMP 0x80 /* discard and send ICMP on failure */
#define IP6_OPT_TYPE_ICMP 0xC0 /* ...only if non-multicast dst */
#define IP6_OPT_MUTABLE 0x20 /* option data may change en route */
/*
* Extension header (chained via {ip6,ext}_nxt, following IPv6 header)
*/
struct ip6_ext_hdr {
uint8_t ext_nxt; /* next header */
uint8_t ext_len; /* following length in units of 8 octets */
union {
struct ip6_ext_data_routing routing;
struct ip6_ext_data_fragment fragment;
} ext_data;
} __attribute__((__packed__));
#ifndef __GNUC__
# pragma pack()
#endif
/*
* Reserved addresses
*/
#define IP6_ADDR_UNSPEC \
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
#define IP6_ADDR_LOOPBACK \
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"
#define ip6_pack_hdr(hdr, fc, fl, plen, nxt, hlim, src, dst) do { \
struct ip6_hdr *ip6 = (struct ip6_hdr *)(hdr); \
ip6->ip6_flow = htonl(((uint32_t)(fc) << 28) & \
(IP6_FLOWLABEL_MASK | (fl))); \
ip6->ip6_vfc = (IP6_VERSION | ((fc) >> 4)); \
ip6->ip6_plen = htons((plen)); \
ip6->ip6_nxt = (nxt); ip6->ip6_hlim = (hlim); \
memmove(&ip6->ip6_src, &(src), IP6_ADDR_LEN); \
memmove(&ip6->ip6_dst, &(dst), IP6_ADDR_LEN); \
} while (0);
__BEGIN_DECLS
char *ip6_ntop(const ip6_addr_t *ip6, char *dst, size_t size);
int ip6_pton(const char *src, ip6_addr_t *dst);
char *ip6_ntoa(const ip6_addr_t *ip6);
#define ip6_aton ip6_pton
void ip6_checksum(void *buf, size_t len);
__END_DECLS
#endif /* DNET_IP6_H */

117
ext/dnet/dnet/os.h Normal file
View file

@ -0,0 +1,117 @@
/*
* os.h
*
* Sleazy OS-specific defines.
*
* Copyright (c) 2000 Dug Song <dugsong@monkey.org>
*
* $Id: os.h,v 1.10 2004/05/04 03:19:42 dugsong Exp $
*/
#ifndef DNET_OS_H
#define DNET_OS_H
#ifdef _WIN32
# include <windows.h>
# include <winsock2.h>
# include <stdint.h>
/* XXX */
# undef IP_OPT_LSRR
# undef IP_OPT_TS
# undef IP_OPT_RR
# undef IP_OPT_SSRR
#else
# include <sys/param.h>
# include <sys/types.h>
# include <sys/socket.h>
# include <netinet/in.h>
# include <arpa/inet.h>
# include <netdb.h>
# ifdef __bsdi__
# include <machine/types.h>
typedef u_int8_t uint8_t;
typedef u_int16_t uint16_t;
typedef u_int32_t uint32_t;
typedef u_int64_t uint64_t;
# else
# include <inttypes.h>
# endif
#endif
#define DNET_LIL_ENDIAN 1234
#define DNET_BIG_ENDIAN 4321
/* BSD and IRIX */
#ifdef BYTE_ORDER
#if BYTE_ORDER == LITTLE_ENDIAN
# define DNET_BYTESEX DNET_LIL_ENDIAN
#elif BYTE_ORDER == BIG_ENDIAN
# define DNET_BYTESEX DNET_BIG_ENDIAN
#endif
#endif
/* Linux */
#ifdef __BYTE_ORDER
#if __BYTE_ORDER == __LITTLE_ENDIAN
# define DNET_BYTESEX DNET_LIL_ENDIAN
#elif __BYTE_ORDER == __BIG_ENDIAN
# define DNET_BYTESEX DNET_BIG_ENDIAN
#endif
#endif
/* Solaris */
#if defined(_BIT_FIELDS_LTOH)
# define DNET_BYTESEX DNET_LIL_ENDIAN
#elif defined (_BIT_FIELDS_HTOL)
# define DNET_BYTESEX DNET_BIG_ENDIAN
#endif
/* Nastiness from old BIND code. */
#ifndef DNET_BYTESEX
# if defined(vax) || defined(ns32000) || defined(sun386) || defined(i386) || \
defined(MIPSEL) || defined(_MIPSEL) || defined(BIT_ZERO_ON_RIGHT) || \
defined(__alpha__) || defined(__alpha)
# define DNET_BYTESEX DNET_LIL_ENDIAN
# elif defined(sel) || defined(pyr) || defined(mc68000) || defined(sparc) || \
defined(is68k) || defined(tahoe) || defined(ibm032) || defined(ibm370) || \
defined(MIPSEB) || defined(_MIPSEB) || defined(_IBMR2) || defined(DGUX) ||\
defined(apollo) || defined(__convex__) || defined(_CRAY) || \
defined(__hppa) || defined(__hp9000) || \
defined(__hp9000s300) || defined(__hp9000s700) || defined(__ia64) || \
defined (BIT_ZERO_ON_LEFT) || defined(m68k)
# define DNET_BYTESEX DNET_BIG_ENDIAN
# else
# error "bytesex unknown"
# endif
#endif
/* C++ support. */
#undef __BEGIN_DECLS
#undef __END_DECLS
#ifdef __cplusplus
# define __BEGIN_DECLS extern "C" {
# define __END_DECLS } /* extern "C" */
#else
# define __BEGIN_DECLS
# define __END_DECLS
#endif
/* Support for flexible arrays. */
#undef __flexarr
#if defined(__GNUC__) && ((__GNUC__ > 2) || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97))
/* GCC 2.97 supports C99 flexible array members. */
# define __flexarr []
#else
# ifdef __GNUC__
# define __flexarr [0]
# else
# if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
# define __flexarr []
# else
/* Some other non-C99 compiler. Approximate with [1]. */
# define __flexarr [1]
# endif
# endif
#endif
#endif /* DNET_OS_H */

33
ext/dnet/dnet/rand.h Normal file
View file

@ -0,0 +1,33 @@
/*
* rand.h
*
* Pseudo-random number generation, based on OpenBSD arc4random().
*
* Copyright (c) 2000 Dug Song <dugsong@monkey.org>
* Copyright (c) 1996 David Mazieres <dm@lcs.mit.edu>
*
* $Id: rand.h,v 1.4 2002/04/07 19:01:25 dugsong Exp $
*/
#ifndef DNET_RAND_H
#define DNET_RAND_H
typedef struct rand_handle rand_t;
__BEGIN_DECLS
rand_t *rand_open(void);
int rand_get(rand_t *r, void *buf, size_t len);
int rand_set(rand_t *r, const void *seed, size_t len);
int rand_add(rand_t *r, const void *buf, size_t len);
uint8_t rand_uint8(rand_t *r);
uint16_t rand_uint16(rand_t *r);
uint32_t rand_uint32(rand_t *r);
int rand_shuffle(rand_t *r, void *base, size_t nmemb, size_t size);
rand_t *rand_close(rand_t *r);
__END_DECLS
#endif /* DNET_RAND_H */

35
ext/dnet/dnet/route.h Normal file
View file

@ -0,0 +1,35 @@
/*
* route.c
*
* Kernel route table operations.
*
* Copyright (c) 2000 Dug Song <dugsong@monkey.org>
*
* $Id: route.h,v 1.6 2002/02/04 04:02:22 dugsong Exp $
*/
#ifndef DNET_ROUTE_H
#define DNET_ROUTE_H
/*
* Routing table entry
*/
struct route_entry {
struct addr route_dst; /* destination address */
struct addr route_gw; /* gateway address */
};
typedef struct route_handle route_t;
typedef int (*route_handler)(const struct route_entry *entry, void *arg);
__BEGIN_DECLS
route_t *route_open(void);
int route_add(route_t *r, const struct route_entry *entry);
int route_delete(route_t *r, const struct route_entry *entry);
int route_get(route_t *r, struct route_entry *entry);
int route_loop(route_t *r, route_handler callback, void *arg);
route_t *route_close(route_t *r);
__END_DECLS
#endif /* DNET_ROUTE_H */

158
ext/dnet/dnet/tcp.h Normal file
View file

@ -0,0 +1,158 @@
/*
* tcp.h
*
* Transmission Control Protocol (RFC 793).
*
* Copyright (c) 2000 Dug Song <dugsong@monkey.org>
*
* $Id: tcp.h,v 1.17 2004/02/23 10:02:11 dugsong Exp $
*/
#ifndef DNET_TCP_H
#define DNET_TCP_H
#define TCP_HDR_LEN 20 /* base TCP header length */
#define TCP_OPT_LEN 2 /* base TCP option length */
#define TCP_OPT_LEN_MAX 40
#define TCP_HDR_LEN_MAX (TCP_HDR_LEN + TCP_OPT_LEN_MAX)
#ifndef __GNUC__
# define __attribute__(x)
# pragma pack(1)
#endif
/*
* TCP header, without options
*/
struct tcp_hdr {
uint16_t th_sport; /* source port */
uint16_t th_dport; /* destination port */
uint32_t th_seq; /* sequence number */
uint32_t th_ack; /* acknowledgment number */
#if DNET_BYTESEX == DNET_BIG_ENDIAN
uint8_t th_off:4, /* data offset */
th_x2:4; /* (unused) */
#elif DNET_BYTESEX == DNET_LIL_ENDIAN
uint8_t th_x2:4,
th_off:4;
#else
# error "need to include <dnet.h>"
#endif
uint8_t th_flags; /* control flags */
uint16_t th_win; /* window */
uint16_t th_sum; /* checksum */
uint16_t th_urp; /* urgent pointer */
};
/*
* TCP control flags (th_flags)
*/
#define TH_FIN 0x01 /* end of data */
#define TH_SYN 0x02 /* synchronize sequence numbers */
#define TH_RST 0x04 /* reset connection */
#define TH_PUSH 0x08 /* push */
#define TH_ACK 0x10 /* acknowledgment number set */
#define TH_URG 0x20 /* urgent pointer set */
#define TH_ECE 0x40 /* ECN echo, RFC 3168 */
#define TH_CWR 0x80 /* congestion window reduced */
#define TCP_PORT_MAX 65535 /* maximum port */
#define TCP_WIN_MAX 65535 /* maximum (unscaled) window */
/*
* Sequence number comparison macros
*/
#define TCP_SEQ_LT(a,b) ((int)((a)-(b)) < 0)
#define TCP_SEQ_LEQ(a,b) ((int)((a)-(b)) <= 0)
#define TCP_SEQ_GT(a,b) ((int)((a)-(b)) > 0)
#define TCP_SEQ_GEQ(a,b) ((int)((a)-(b)) >= 0)
/*
* TCP FSM states
*/
#define TCP_STATE_CLOSED 0 /* closed */
#define TCP_STATE_LISTEN 1 /* listening from connection */
#define TCP_STATE_SYN_SENT 2 /* active, have sent SYN */
#define TCP_STATE_SYN_RECEIVED 3 /* have sent and received SYN */
#define TCP_STATE_ESTABLISHED 4 /* established */
#define TCP_STATE_CLOSE_WAIT 5 /* rcvd FIN, waiting for close */
#define TCP_STATE_FIN_WAIT_1 6 /* have closed, sent FIN */
#define TCP_STATE_CLOSING 7 /* closed xchd FIN, await FIN-ACK */
#define TCP_STATE_LAST_ACK 8 /* had FIN and close, await FIN-ACK */
#define TCP_STATE_FIN_WAIT_2 9 /* have closed, FIN is acked */
#define TCP_STATE_TIME_WAIT 10 /* in 2*MSL quiet wait after close */
#define TCP_STATE_MAX 11
/*
* Options (opt_type) - http://www.iana.org/assignments/tcp-parameters
*/
#define TCP_OPT_EOL 0 /* end of option list */
#define TCP_OPT_NOP 1 /* no operation */
#define TCP_OPT_MSS 2 /* maximum segment size */
#define TCP_OPT_WSCALE 3 /* window scale factor, RFC 1072 */
#define TCP_OPT_SACKOK 4 /* SACK permitted, RFC 2018 */
#define TCP_OPT_SACK 5 /* SACK, RFC 2018 */
#define TCP_OPT_ECHO 6 /* echo (obsolete), RFC 1072 */
#define TCP_OPT_ECHOREPLY 7 /* echo reply (obsolete), RFC 1072 */
#define TCP_OPT_TIMESTAMP 8 /* timestamp, RFC 1323 */
#define TCP_OPT_POCONN 9 /* partial order conn, RFC 1693 */
#define TCP_OPT_POSVC 10 /* partial order service, RFC 1693 */
#define TCP_OPT_CC 11 /* connection count, RFC 1644 */
#define TCP_OPT_CCNEW 12 /* CC.NEW, RFC 1644 */
#define TCP_OPT_CCECHO 13 /* CC.ECHO, RFC 1644 */
#define TCP_OPT_ALTSUM 14 /* alt checksum request, RFC 1146 */
#define TCP_OPT_ALTSUMDATA 15 /* alt checksum data, RFC 1146 */
#define TCP_OPT_SKEETER 16 /* Skeeter */
#define TCP_OPT_BUBBA 17 /* Bubba */
#define TCP_OPT_TRAILSUM 18 /* trailer checksum */
#define TCP_OPT_MD5 19 /* MD5 signature, RFC 2385 */
#define TCP_OPT_SCPS 20 /* SCPS capabilities */
#define TCP_OPT_SNACK 21 /* selective negative acks */
#define TCP_OPT_REC 22 /* record boundaries */
#define TCP_OPT_CORRUPT 23 /* corruption experienced */
#define TCP_OPT_SNAP 24 /* SNAP */
#define TCP_OPT_TCPCOMP 26 /* TCP compression filter */
#define TCP_OPT_MAX 27
#define TCP_OPT_TYPEONLY(type) \
((type) == TCP_OPT_EOL || (type) == TCP_OPT_NOP)
/*
* TCP option (following TCP header)
*/
struct tcp_opt {
uint8_t opt_type; /* option type */
uint8_t opt_len; /* option length >= TCP_OPT_LEN */
union tcp_opt_data {
uint16_t mss; /* TCP_OPT_MSS */
uint8_t wscale; /* TCP_OPT_WSCALE */
uint16_t sack[19]; /* TCP_OPT_SACK */
uint32_t echo; /* TCP_OPT_ECHO{REPLY} */
uint32_t timestamp[2]; /* TCP_OPT_TIMESTAMP */
uint32_t cc; /* TCP_OPT_CC{NEW,ECHO} */
uint8_t cksum; /* TCP_OPT_ALTSUM */
uint8_t md5[16]; /* TCP_OPT_MD5 */
uint8_t data8[TCP_OPT_LEN_MAX - TCP_OPT_LEN];
} opt_data;
} __attribute__((__packed__));
#ifndef __GNUC__
# pragma pack()
#endif
#define tcp_pack_hdr(hdr, sport, dport, seq, ack, flags, win, urp) do { \
struct tcp_hdr *tcp_pack_p = (struct tcp_hdr *)(hdr); \
tcp_pack_p->th_sport = htons(sport); \
tcp_pack_p->th_dport = htons(dport); \
tcp_pack_p->th_seq = htonl(seq); \
tcp_pack_p->th_ack = htonl(ack); \
tcp_pack_p->th_x2 = 0; tcp_pack_p->th_off = 5; \
tcp_pack_p->th_flags = flags; \
tcp_pack_p->th_win = htons(win); \
tcp_pack_p->th_urp = htons(urp); \
} while (0)
#endif /* DNET_TCP_H */

32
ext/dnet/dnet/udp.h Normal file
View file

@ -0,0 +1,32 @@
/*
* udp.h
*
* User Datagram Protocol (RFC 768).
*
* Copyright (c) 2000 Dug Song <dugsong@monkey.org>
*
* $Id: udp.h,v 1.8 2002/04/02 05:05:39 dugsong Exp $
*/
#ifndef DNET_UDP_H
#define DNET_UDP_H
#define UDP_HDR_LEN 8
struct udp_hdr {
uint16_t uh_sport; /* source port */
uint16_t uh_dport; /* destination port */
uint16_t uh_ulen; /* udp length (including header) */
uint16_t uh_sum; /* udp checksum */
};
#define UDP_PORT_MAX 65535
#define udp_pack_hdr(hdr, sport, dport, ulen) do { \
struct udp_hdr *udp_pack_p = (struct udp_hdr *)(hdr); \
udp_pack_p->uh_sport = htons(sport); \
udp_pack_p->uh_dport = htons(dport); \
udp_pack_p->uh_ulen = htons(ulen); \
} while (0)
#endif /* DNET_UDP_H */

158
ext/ply/CHANGES Normal file
View file

@ -0,0 +1,158 @@
Version 1.3
------------------------------
12/10/02: jmdyck
Various minor adjustments to the code that Dave checked in today.
Updated test/yacc_{inf,unused}.exp to reflect today's changes.
12/10/02: beazley
Incorporated a variety of minor bug fixes to empty production
handling and infinite recursion checking. Contributed by
Michael Dyck.
12/10/02: beazley
Removed bogus recover() method call in yacc.restart()
Version 1.2
------------------------------
11/27/02: beazley
Lexer and parser objects are now available as an attribute
of tokens and slices respectively. For example:
def t_NUMBER(t):
r'\d+'
print t.lexer
def p_expr_plus(t):
'expr: expr PLUS expr'
print t.lexer
print t.parser
This can be used for state management (if needed).
10/31/02: beazley
Modified yacc.py to work with Python optimize mode. To make
this work, you need to use
yacc.yacc(optimize=1)
Furthermore, you need to first run Python in normal mode
to generate the necessary parsetab.py files. After that,
you can use python -O or python -OO.
Note: optimized mode turns off a lot of error checking.
Only use when you are sure that your grammar is working.
Make sure parsetab.py is up to date!
10/30/02: beazley
Added cloning of Lexer objects. For example:
import copy
l = lex.lex()
lc = copy.copy(l)
l.input("Some text")
lc.input("Some other text")
...
This might be useful if the same "lexer" is meant to
be used in different contexts---or if multiple lexers
are running concurrently.
10/30/02: beazley
Fixed subtle bug with first set computation and empty productions.
Patch submitted by Michael Dyck.
10/30/02: beazley
Fixed error messages to use "filename:line: message" instead
of "filename:line. message". This makes error reporting more
friendly to emacs. Patch submitted by François Pinard.
10/30/02: beazley
Improvements to parser.out file. Terminals and nonterminals
are sorted instead of being printed in random order.
Patch submitted by François Pinard.
10/30/02: beazley
Improvements to parser.out file output. Rules are now printed
in a way that's easier to understand. Contributed by Russ Cox.
10/30/02: beazley
Added 'nonassoc' associativity support. This can be used
to disable the chaining of operators like a < b < c.
To use, simply specify 'nonassoc' in the precedence table
precedence = (
('nonassoc', 'LESSTHAN', 'GREATERTHAN'), # Nonassociative operators
('left', 'PLUS', 'MINUS'),
('left', 'TIMES', 'DIVIDE'),
('right', 'UMINUS'), # Unary minus operator
)
Patch contributed by Russ Cox.
10/30/02: beazley
Modified the lexer to provide optional support for Python -O and -OO
modes. To make this work, Python *first* needs to be run in
unoptimized mode. This reads the lexing information and creates a
file "lextab.py". Then, run lex like this:
# module foo.py
...
...
lex.lex(optimize=1)
Once the lextab file has been created, subsequent calls to
lex.lex() will read data from the lextab file instead of using
introspection. In optimized mode (-O, -OO) everything should
work normally despite the loss of doc strings.
To change the name of the file 'lextab.py' use the following:
lex.lex(lextab="footab")
(this creates a file footab.py)
Version 1.1 October 25, 2001
------------------------------
10/25/01: beazley
Modified the table generator to produce much more compact data.
This should greatly reduce the size of the parsetab.py[c] file.
Caveat: the tables still need to be constructed so a little more
work is done in parsetab on import.
10/25/01: beazley
There may be a possible bug in the cycle detector that reports errors
about infinite recursion. I'm having a little trouble tracking it
down, but if you get this problem, you can disable the cycle
detector as follows:
yacc.yacc(check_recursion = 0)
10/25/01: beazley
Fixed a bug in lex.py that sometimes caused illegal characters to be
reported incorrectly. Reported by Sverre Jørgensen.
7/8/01 : beazley
Added a reference to the underlying lexer object when tokens are handled by
functions. The lexer is available as the 'lexer' attribute. This
was added to provide better lexing support for languages such as Fortran
where certain types of tokens can't be conveniently expressed as regular
expressions (and where the tokenizing function may want to perform a
little backtracking). Suggested by Pearu Peterson.
6/20/01 : beazley
Modified yacc() function so that an optional starting symbol can be specified.
For example:
yacc.yacc(start="statement")
Normally yacc always treats the first production rule as the starting symbol.
However, if you are debugging your grammar it may be useful to specify
an alternative starting symbol. Idea suggested by Rich Salz.
Version 1.0 June 18, 2001
--------------------------
Initial public offering

504
ext/ply/COPYING Normal file
View file

@ -0,0 +1,504 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).
To apply these terms, attach the following notices to the library. It is
safest to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.
<one line to give the library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!

249
ext/ply/README Normal file
View file

@ -0,0 +1,249 @@
PLY (Python Lex-Yacc) Version 1.2 (November 27, 2002)
David M. Beazley
Department of Computer Science
University of Chicago
Chicago, IL 60637
beazley@cs.uchicago.edu
Copyright (C) 2001 David M. Beazley
$Header: /home/stever/bk/newmem2/ext/ply/README 1.1 03/06/06 14:53:34-00:00 stever@ $
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
See the file COPYING for a complete copy of the LGPL.
Introduction
============
PLY is a 100% Python implementation of the common parsing tools lex
and yacc. Although several other parsing tools are available for
Python, there are several reasons why you might want to consider PLY:
- The tools are very closely modeled after traditional lex/yacc.
If you know how to use these tools in C, you will find PLY
to be similar.
- PLY provides *very* extensive error reporting and diagnostic
information to assist in parser construction. The original
implementation was developed for instructional purposes. As
a result, the system tries to identify the most common types
of errors made by novice users.
- PLY provides full support for empty productions, error recovery,
precedence specifiers, and moderately ambiguous grammars.
- Parsing is based on LR-parsing which is fast, memory efficient,
better suited to large grammars, and which has a number of nice
properties when dealing with syntax errors and other parsing problems.
Currently, PLY builds its parsing tables using the SLR algorithm which
is slightly weaker than LALR(1) used in traditional yacc.
- Like John Aycock's excellent SPARK toolkit, PLY uses Python
reflection to build lexers and parsers. This greatly simplifies
the task of parser construction since it reduces the number of files
and eliminates the need to run a separate lex/yacc tool before
running your program.
- PLY can be used to build parsers for "real" programming languages.
Although it is not ultra-fast due to its Python implementation,
PLY can be used to parse grammars consisting of several hundred
rules (as might be found for a language like C). The lexer and LR
parser are also reasonably efficient when parsing typically
sized programs.
The original version of PLY was developed for an Introduction to
Compilers course where students used it to build a compiler for a
simple Pascal-like language. Their compiler had to include lexical
analysis, parsing, type checking, type inference, and generation of
assembly code for the SPARC processor. Because of this, the current
implementation has been extensively tested and debugged. In addition,
most of the API and error checking steps have been adapted to address
common usability problems.
How to Use
==========
PLY consists of two files : lex.py and yacc.py. To use the system,
simply copy these files to your project and import them like standard
Python modules.
The file doc/ply.html contains complete documentation on how to use
the system.
The example directory contains several different examples including a
PLY specification for ANSI C as given in K&R 2nd Ed. Note: To use
the examples, you will need to copy the lex.py and yacc.py files to
the example directory.
A simple example is found at the end of this document
Requirements
============
PLY requires the use of Python 2.0 or greater. It should work on
just about any platform.
Resources
=========
More information about PLY can be obtained on the PLY webpage at:
http://systems.cs.uchicago.edu/ply
For a detailed overview of parsing theory, consult the excellent
book "Compilers : Principles, Techniques, and Tools" by Aho, Sethi, and
Ullman. The topics found in "Lex & Yacc" by Levine, Mason, and Brown
may also be useful.
Given that this is the first release, I welcome your comments on how
to improve the current implementation. See the TODO file for things that
still need to be done.
Acknowledgments
===============
A special thanks is in order for all of the students in CS326 who
suffered through about 25 different versions of these tools :-).
Example
=======
Here is a simple example showing a PLY implementation of a calculator with variables.
# -----------------------------------------------------------------------------
# calc.py
#
# A simple calculator with variables.
# -----------------------------------------------------------------------------
tokens = (
'NAME','NUMBER',
'PLUS','MINUS','TIMES','DIVIDE','EQUALS',
'LPAREN','RPAREN',
)
# Tokens
t_PLUS = r'\+'
t_MINUS = r'-'
t_TIMES = r'\*'
t_DIVIDE = r'/'
t_EQUALS = r'='
t_LPAREN = r'\('
t_RPAREN = r'\)'
t_NAME = r'[a-zA-Z_][a-zA-Z0-9_]*'
def t_NUMBER(t):
r'\d+'
try:
t.value = int(t.value)
except ValueError:
print "Integer value too large", t.value
t.value = 0
return t
# Ignored characters
t_ignore = " \t"
def t_newline(t):
r'\n+'
t.lineno += t.value.count("\n")
def t_error(t):
print "Illegal character '%s'" % t.value[0]
t.skip(1)
# Build the lexer
import lex
lex.lex()
# Precedence rules for the arithmetic operators
precedence = (
('left','PLUS','MINUS'),
('left','TIMES','DIVIDE'),
('right','UMINUS'),
)
# dictionary of names (for storing variables)
names = { }
def p_statement_assign(t):
'statement : NAME EQUALS expression'
names[t[1]] = t[3]
def p_statement_expr(t):
'statement : expression'
print t[1]
def p_expression_binop(t):
'''expression : expression PLUS expression
| expression MINUS expression
| expression TIMES expression
| expression DIVIDE expression'''
if t[2] == '+' : t[0] = t[1] + t[3]
elif t[2] == '-': t[0] = t[1] - t[3]
elif t[2] == '*': t[0] = t[1] * t[3]
elif t[2] == '/': t[0] = t[1] / t[3]
def p_expression_uminus(t):
'expression : MINUS expression %prec UMINUS'
t[0] = -t[2]
def p_expression_group(t):
'expression : LPAREN expression RPAREN'
t[0] = t[2]
def p_expression_number(t):
'expression : NUMBER'
t[0] = t[1]
def p_expression_name(t):
'expression : NAME'
try:
t[0] = names[t[1]]
except LookupError:
print "Undefined name '%s'" % t[1]
t[0] = 0
def p_error(t):
print "Syntax error at '%s'" % t.value
import yacc
yacc.yacc()
while 1:
try:
s = raw_input('calc > ')
except EOFError:
break
yacc.parse(s)

22
ext/ply/TODO Normal file
View file

@ -0,0 +1,22 @@
The PLY to-do list:
$Header: /home/stever/bk/newmem2/ext/ply/TODO 1.1 03/06/06 14:53:34-00:00 stever@ $
1. Create a Python package using distutils
2. More interesting parsing examples.
3. Work on the ANSI C grammar so that it can actually parse C programs. To do this,
some extra code needs to be added to the lexer to deal with typedef names and enumeration
constants.
4. Get LALR(1) to work. Hard, but not impossible.
5. More tests in the test directory.
6. Performance improvements and cleanup in yacc.py.
7. More documentation.
8. Lots and lots of cleanup.

1642
ext/ply/doc/ply.html Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,2 @@
This example is incomplete. Was going to specify an ANSI C parser.
This is part of it.

View file

@ -0,0 +1,161 @@
# ----------------------------------------------------------------------
# clex.py
#
# A lexer for ANSI C.
# ----------------------------------------------------------------------
import lex
# Reserved words
reserved = (
'AUTO', 'BREAK', 'CASE', 'CHAR', 'CONST', 'CONTINUE', 'DEFAULT', 'DO', 'DOUBLE',
'ELSE', 'ENUM', 'EXTERN', 'FLOAT', 'FOR', 'GOTO', 'IF', 'INT', 'LONG', 'REGISTER',
'RETURN', 'SHORT', 'SIGNED', 'SIZEOF', 'STATIC', 'STRUCT', 'SWITCH', 'TYPEDEF',
'UNION', 'UNSIGNED', 'VOID', 'VOLATILE', 'WHILE',
)
tokens = reserved + (
# Literals (identifier, integer constant, float constant, string constant, char const)
'ID', 'TYPEID', 'ICONST', 'FCONST', 'SCONST', 'CCONST',
# Operators (+,-,*,/,%,|,&,~,^,<<,>>, ||, &&, !, <, <=, >, >=, ==, !=)
'PLUS', 'MINUS', 'TIMES', 'DIVIDE', 'MOD',
'OR', 'AND', 'NOT', 'XOR', 'LSHIFT', 'RSHIFT',
'LOR', 'LAND', 'LNOT',
'LT', 'LE', 'GT', 'GE', 'EQ', 'NE',
# Assignment (=, *=, /=, %=, +=, -=, <<=, >>=, &=, ^=, |=)
'EQUALS', 'TIMESEQUAL', 'DIVEQUAL', 'MODEQUAL', 'PLUSEQUAL', 'MINUSEQUAL',
'LSHIFTEQUAL','RSHIFTEQUAL', 'ANDEQUAL', 'XOREQUAL', 'OREQUAL',
# Increment/decrement (++,--)
'PLUSPLUS', 'MINUSMINUS',
# Structure dereference (->)
'ARROW',
# Conditional operator (?)
'CONDOP',
# Delimeters ( ) [ ] { } , . ; :
'LPAREN', 'RPAREN',
'LBRACKET', 'RBRACKET',
'LBRACE', 'RBRACE',
'COMMA', 'PERIOD', 'SEMI', 'COLON',
# Ellipsis (...)
'ELLIPSIS',
)
# Completely ignored characters
t_ignore = ' \t\x0c'
# Newlines
def t_NEWLINE(t):
r'\n+'
t.lineno += t.value.count("\n")
# Operators
t_PLUS = r'\+'
t_MINUS = r'-'
t_TIMES = r'\*'
t_DIVIDE = r'/'
t_MOD = r'%'
t_OR = r'\|'
t_AND = r'&'
t_NOT = r'~'
t_XOR = r'^'
t_LSHIFT = r'<<'
t_RSHIFT = r'>>'
t_LOR = r'\|\|'
t_LAND = r'&&'
t_LNOT = r'!'
t_LT = r'<'
t_GT = r'>'
t_LE = r'<='
t_GE = r'>='
t_EQ = r'=='
t_NE = r'!='
# Assignment operators
t_EQUALS = r'='
t_TIMESEQUAL = r'\*='
t_DIVEQUAL = r'/='
t_MODEQUAL = r'%='
t_PLUSEQUAL = r'\+='
t_MINUSEQUAL = r'-='
t_LSHIFTEQUAL = r'<<='
t_RSHIFTEQUAL = r'>>='
t_ANDEQUAL = r'&='
t_OREQUAL = r'\|='
t_XOREQUAL = r'^='
# Increment/decrement
t_PLUSPLUS = r'\+\+'
t_MINUSMINUS = r'--'
# ->
t_ARROW = r'->'
# ?
t_CONDOP = r'\?'
# Delimeters
t_LPAREN = r'\('
t_RPAREN = r'\)'
t_LBRACKET = r'\['
t_RBRACKET = r'\]'
t_LBRACE = r'\{'
t_RBRACE = r'\}'
t_COMMA = r','
t_PERIOD = r'\.'
t_SEMI = r';'
t_COLON = r':'
t_ELLIPSIS = r'\.\.\.'
# Identifiers and reserved words
reserved_map = { }
for r in reserved:
reserved_map[r.lower()] = r
def t_ID(t):
r'[A-Za-z_][\w_]*'
t.type = reserved_map.get(t.value,"ID")
return t
# Integer literal
t_ICONST = r'\d+([uU]|[lL]|[uU][lL]|[lL][uU])?'
# Floating literal
t_FCONST = r'((\d+)(\.\d+)(e(\+|-)?(\d+))? | (\d+)e(\+|-)?(\d+))([lL]|[fF])?'
# String literal
t_SCONST = r'\"([^\\\n]|(\\.))*?\"'
# Character constant 'c' or L'c'
t_CCONST = r'(L)?\'([^\\\n]|(\\.))*?\''
# Comments
def t_comment(t):
r' /\*(.|\n)*?\*/'
t.lineno += t.value.count('\n')
# Preprocessor directive (ignored)
def t_preprocessor(t):
r'\#(.)*?\n'
t.lineno += 1
def t_error(t):
print "Illegal character %s" % repr(t.value[0])
t.skip(1)
lexer = lex.lex(optimize=1)
if __name__ == "__main__":
lex.runmain(lexer)

View file

@ -0,0 +1,859 @@
# -----------------------------------------------------------------------------
# cparse.py
#
# Simple parser for ANSI C. Based on the grammar in K&R, 2nd Ed.
# -----------------------------------------------------------------------------
import yacc
import clex
# Get the token map
tokens = clex.tokens
# translation-unit:
def p_translation_unit_1(t):
'translation_unit : external_declaration'
pass
def p_translation_unit_2(t):
'translation_unit : translation_unit external_declaration'
pass
# external-declaration:
def p_external_declaration_1(t):
'external_declaration : function_definition'
pass
def p_external_declaration_2(t):
'external_declaration : declaration'
pass
# function-definition:
def p_function_definition_1(t):
'function_definition : declaration_specifiers declarator declaration_list compound_statement'
pass
def p_function_definition_2(t):
'function_definition : declarator declaration_list compound_statement'
pass
def p_function_definition_3(t):
'function_definition : declarator compound_statement'
pass
def p_function_definition_4(t):
'function_definition : declaration_specifiers declarator compound_statement'
pass
# declaration:
def p_declaration_1(t):
'declaration : declaration_specifiers init_declarator_list SEMI'
pass
def p_declaration_2(t):
'declaration : declaration_specifiers SEMI'
pass
# declaration-list:
def p_declaration_list_1(t):
'declaration_list : declaration'
pass
def p_declaration_list_2(t):
'declaration_list : declaration_list declaration '
pass
# declaration-specifiers
def p_declaration_specifiers_1(t):
'declaration_specifiers : storage_class_specifier declaration_specifiers'
pass
def p_declaration_specifiers_2(t):
'declaration_specifiers : type_specifier declaration_specifiers'
pass
def p_declaration_specifiers_3(t):
'declaration_specifiers : type_qualifier declaration_specifiers'
pass
def p_declaration_specifiers_4(t):
'declaration_specifiers : storage_class_specifier'
pass
def p_declaration_specifiers_5(t):
'declaration_specifiers : type_specifier'
pass
def p_declaration_specifiers_6(t):
'declaration_specifiers : type_qualifier'
pass
# storage-class-specifier
def p_storage_class_specifier(t):
'''storage_class_specifier : AUTO
| REGISTER
| STATIC
| EXTERN
| TYPEDEF
'''
pass
# type-specifier:
def p_type_specifier(t):
'''type_specifier : VOID
| CHAR
| SHORT
| INT
| LONG
| FLOAT
| DOUBLE
| SIGNED
| UNSIGNED
| struct_or_union_specifier
| enum_specifier
| TYPEID
'''
pass
# type-qualifier:
def p_type_qualifier(t):
'''type_qualifier : CONST
| VOLATILE'''
pass
# struct-or-union-specifier
def p_struct_or_union_specifier_1(t):
'struct_or_union_specifier : struct_or_union ID LBRACE struct_declaration_list RBRACE'
pass
def p_struct_or_union_specifier_2(t):
'struct_or_union_specifier : struct_or_union LBRACE struct_declaration_list RBRACE'
pass
def p_struct_or_union_specifier_3(t):
'struct_or_union_specifier : struct_or_union ID'
pass
# struct-or-union:
def p_struct_or_union(t):
'''struct_or_union : STRUCT
| UNION
'''
pass
# struct-declaration-list:
def p_struct_declaration_list_1(t):
'struct_declaration_list : struct_declaration'
pass
def p_struct_declaration_list_2(t):
'struct_declaration_list : struct_declarator_list struct_declaration'
pass
# init-declarator-list:
def p_init_declarator_list_1(t):
'init_declarator_list : init_declarator'
pass
def p_init_declarator_list_2(t):
'init_declarator_list : init_declarator_list COMMA init_declarator'
pass
# init-declarator
def p_init_declarator_1(t):
'init_declarator : declarator'
pass
def p_init_declarator_2(t):
'init_declarator : declarator EQUALS initializer'
pass
# struct-declaration:
def p_struct_declaration(t):
'struct_declaration : specifier_qualifier_list struct_declarator_list SEMI'
pass
# specifier-qualifier-list:
def p_specifier_qualifier_list_1(t):
'specifier_qualifier_list : type_specifier specifier_qualifier_list'
pass
def p_specifier_qualifier_list_2(t):
'specifier_qualifier_list : type_specifier'
pass
def p_specifier_qualifier_list_3(t):
'specifier_qualifier_list : type_qualifier specifier_qualifier_list'
pass
def p_specifier_qualifier_list_4(t):
'specifier_qualifier_list : type_qualifier'
pass
# struct-declarator-list:
def p_struct_declarator_list_1(t):
'struct_declarator_list : struct_declarator'
pass
def p_struct_declarator_list_2(t):
'struct_declarator_list : struct_declarator_list COMMA struct_declarator'
pass
# struct-declarator:
def p_struct_declarator_1(t):
'struct_declarator : declarator'
pass
def p_struct_declarator_2(t):
'struct_declarator : declarator COLON constant_expression'
pass
def p_struct_declarator_3(t):
'struct_declarator : COLON constant_expression'
pass
# enum-specifier:
def p_enum_specifier_1(t):
'enum_specifier : ENUM ID LBRACE enumerator_list RBRACE'
pass
def p_enum_specifier_2(t):
'enum_specifier : ENUM LBRACE enumerator_list RBRACE'
pass
def p_enum_specifier_3(t):
'enum_specifier : ENUM ID'
pass
# enumerator_list:
def p_enumerator_list_1(t):
'enumerator_list : enumerator'
pass
def p_enumerator_list_2(t):
'enumerator_list : enumerator_list COMMA enumerator'
pass
# enumerator:
def p_enumerator_1(t):
'enumerator : ID'
pass
def p_enumerator_2(t):
'enumerator : ID EQUALS constant_expression'
pass
# declarator:
def p_declarator_1(t):
'declarator : pointer direct_declarator'
pass
def p_declarator_2(t):
'declarator : direct_declarator'
pass
# direct-declarator:
def p_direct_declarator_1(t):
'direct_declarator : ID'
pass
def p_direct_declarator_2(t):
'direct_declarator : LPAREN declarator RPAREN'
pass
def p_direct_declarator_3(t):
'direct_declarator : direct_declarator LBRACKET constant_expression_opt RBRACKET'
pass
def p_direct_declarator_4(t):
'direct_declarator : direct_declarator LPAREN parameter_type_list RPAREN '
pass
def p_direct_declarator_5(t):
'direct_declarator : direct_declarator LPAREN identifier_list RPAREN '
pass
def p_direct_declarator_6(t):
'direct_declarator : direct_declarator LPAREN RPAREN '
pass
# pointer:
def p_pointer_1(t):
'pointer : TIMES type_qualifier_list'
pass
def p_pointer_2(t):
'pointer : TIMES'
pass
def p_pointer_3(t):
'pointer : TIMES type_qualifier_list pointer'
pass
def p_pointer_4(t):
'pointer : TIMES pointer'
pass
# type-qualifier-list:
def p_type_qualifier_list_1(t):
'type_qualifier_list : type_qualifier'
pass
def p_type_qualifier_list_2(t):
'type_qualifier_list : type_qualifier_list type_qualifier'
pass
# parameter-type-list:
def p_parameter_type_list_1(t):
'parameter_type_list : parameter_list'
pass
def p_parameter_type_list_2(t):
'parameter_type_list : parameter_list COMMA ELLIPSIS'
pass
# parameter-list:
def p_parameter_list_1(t):
'parameter_list : parameter_declaration'
pass
def p_parameter_list_2(t):
'parameter_list : parameter_list COMMA parameter_declaration'
pass
# parameter-declaration:
def p_parameter_declaration_1(t):
'parameter_declaration : declaration_specifiers declarator'
pass
def p_parameter_declaration_2(t):
'parameter_declaration : declaration_specifiers abstract_declarator_opt'
pass
# identifier-list:
def p_identifier_list_1(t):
'identifier_list : ID'
pass
def p_identifier_list_2(t):
'identifier_list : identifier_list COMMA ID'
pass
# initializer:
def p_initializer_1(t):
'initializer : assignment_expression'
pass
def p_initializer_2(t):
'''initializer : LBRACE initializer_list RBRACE
| LBRACE initializer_list COMMA RBRACE'''
pass
# initializer-list:
def p_initializer_list_1(t):
'initializer_list : initializer'
pass
def p_initializer_list_2(t):
'initializer_list : initializer_list COMMA initializer'
pass
# type-name:
def p_type_name(t):
'type_name : specifier_qualifier_list abstract_declarator_opt'
pass
def p_abstract_declarator_opt_1(t):
'abstract_declarator_opt : empty'
pass
def p_abstract_declarator_opt_2(t):
'abstract_declarator_opt : abstract_declarator'
pass
# abstract-declarator:
def p_abstract_declarator_1(t):
'abstract_declarator : pointer '
pass
def p_abstract_declarator_2(t):
'abstract_declarator : pointer direct_abstract_declarator'
pass
def p_abstract_declarator_3(t):
'abstract_declarator : direct_abstract_declarator'
pass
# direct-abstract-declarator:
def p_direct_abstract_declarator_1(t):
'direct_abstract_declarator : LPAREN abstract_declarator RPAREN'
pass
def p_direct_abstract_declarator_2(t):
'direct_abstract_declarator : direct_abstract_declarator LBRACKET constant_expression_opt RBRACKET'
pass
def p_direct_abstract_declarator_3(t):
'direct_abstract_declarator : LBRACKET constant_expression_opt RBRACKET'
pass
def p_direct_abstract_declarator_4(t):
'direct_abstract_declarator : direct_abstract_declarator LPAREN parameter_type_list_opt RPAREN'
pass
def p_direct_abstract_declarator_5(t):
'direct_abstract_declarator : LPAREN parameter_type_list_opt RPAREN'
pass
# Optional fields in abstract declarators
def p_constant_expression_opt_1(t):
'constant_expression_opt : empty'
pass
def p_constant_expression_opt_2(t):
'constant_expression_opt : constant_expression'
pass
def p_parameter_type_list_opt_1(t):
'parameter_type_list_opt : empty'
pass
def p_parameter_type_list_opt_2(t):
'parameter_type_list_opt : parameter_type_list'
pass
# statement:
def p_statement(t):
'''
statement : labeled_statement
| expression_statement
| compound_statement
| selection_statement
| iteration_statement
| jump_statement
'''
pass
# labeled-statement:
def p_labeled_statement_1(t):
'labeled_statement : ID COLON statement'
pass
def p_labeled_statement_2(t):
'labeled_statement : CASE constant_expression COLON statement'
pass
def p_labeled_statement_3(t):
'labeled_statement : DEFAULT COLON statement'
pass
# expression-statement:
def p_expression_statement(t):
'expression_statement : expression_opt SEMI'
pass
# compound-statement:
def p_compound_statement_1(t):
'compound_statement : LBRACE declaration_list statement_list RBRACE'
pass
def p_compound_statement_2(t):
'compound_statement : LBRACE statement_list RBRACE'
pass
def p_compound_statement_3(t):
'compound_statement : LBRACE declaration_list RBRACE'
pass
def p_compound_statement_4(t):
'compound_statement : LBRACE RBRACE'
pass
# statement-list:
def p_statement_list_1(t):
'statement_list : statement'
pass
def p_statement_list_2(t):
'statement_list : statement_list statement'
pass
# selection-statement
def p_selection_statement_1(t):
'selection_statement : IF LPAREN expression RPAREN statement'
pass
def p_selection_statement_2(t):
'selection_statement : IF LPAREN expression RPAREN statement ELSE statement '
pass
def p_selection_statement_3(t):
'selection_statement : SWITCH LPAREN expression RPAREN statement '
pass
# iteration_statement:
def p_iteration_statement_1(t):
'iteration_statement : WHILE LPAREN expression RPAREN statement'
pass
def p_iteration_statement_2(t):
'iteration_statement : FOR LPAREN expression_opt SEMI expression_opt SEMI expression_opt RPAREN statement '
pass
def p_iteration_statement_3(t):
'iteration_statement : DO statement WHILE LPAREN expression RPAREN SEMI'
pass
# jump_statement:
def p_jump_statement_1(t):
'jump_statement : GOTO ID SEMI'
pass
def p_jump_statement_2(t):
'jump_statement : CONTINUE SEMI'
pass
def p_jump_statement_3(t):
'jump_statement : BREAK SEMI'
pass
def p_jump_statement_4(t):
'jump_statement : RETURN expression_opt SEMI'
pass
def p_expression_opt_1(t):
'expression_opt : empty'
pass
def p_expression_opt_2(t):
'expression_opt : expression'
pass
# expression:
def p_expression_1(t):
'expression : assignment_expression'
pass
def p_expression_2(t):
'expression : expression COMMA assignment_expression'
pass
# assigment_expression:
def p_assignment_expression_1(t):
'assignment_expression : conditional_expression'
pass
def p_assignment_expression_2(t):
'assignment_expression : unary_expression assignment_operator assignment_expression'
pass
# assignment_operator:
def p_assignment_operator(t):
'''
assignment_operator : EQUALS
| TIMESEQUAL
| DIVEQUAL
| MODEQUAL
| PLUSEQUAL
| MINUSEQUAL
| LSHIFTEQUAL
| RSHIFTEQUAL
| ANDEQUAL
| OREQUAL
| XOREQUAL
'''
pass
# conditional-expression
def p_conditional_expression_1(t):
'conditional_expression : logical_or_expression'
pass
def p_conditional_expression_2(t):
'conditional_expression : logical_or_expression CONDOP expression COLON conditional_expression '
pass
# constant-expression
def p_constant_expression(t):
'constant_expression : conditional_expression'
pass
# logical-or-expression
def p_logical_or_expression_1(t):
'logical_or_expression : logical_and_expression'
pass
def p_logical_or_expression_2(t):
'logical_or_expression : logical_or_expression LOR logical_and_expression'
pass
# logical-and-expression
def p_logical_and_expression_1(t):
'logical_and_expression : inclusive_or_expression'
pass
def p_logical_and_expression_2(t):
'logical_and_expression : logical_and_expression LAND inclusive_or_expression'
pass
# inclusive-or-expression:
def p_inclusive_or_expression_1(t):
'inclusive_or_expression : exclusive_or_expression'
pass
def p_inclusive_or_expression_2(t):
'inclusive_or_expression : inclusive_or_expression OR exclusive_or_expression'
pass
# exclusive-or-expression:
def p_exclusive_or_expression_1(t):
'exclusive_or_expression : and_expression'
pass
def p_exclusive_or_expression_2(t):
'exclusive_or_expression : exclusive_or_expression XOR and_expression'
pass
# AND-expression
def p_and_expression_1(t):
'and_expression : equality_expression'
pass
def p_and_expression_2(t):
'and_expression : and_expression AND equality_expression'
pass
# equality-expression:
def p_equality_expression_1(t):
'equality_expression : relational_expression'
pass
def p_equality_expression_2(t):
'equality_expression : equality_expression EQ relational_expression'
pass
def p_equality_expression_3(t):
'equality_expression : equality_expression NE relational_expression'
pass
# relational-expression:
def p_relational_expression_1(t):
'relational_expression : shift_expression'
pass
def p_relational_expression_2(t):
'relational_expression : relational_expression LT shift_expression'
pass
def p_relational_expression_3(t):
'relational_expression : relational_expression GT shift_expression'
pass
def p_relational_expression_4(t):
'relational_expression : relational_expression LE shift_expression'
pass
def p_relational_expression_5(t):
'relational_expression : relational_expression GE shift_expression'
pass
# shift-expression
def p_shift_expression_1(t):
'shift_expression : additive_expression'
pass
def p_shift_expression_2(t):
'shift_expression : shift_expression LSHIFT additive_expression'
pass
def p_shift_expression_3(t):
'shift_expression : shift_expression RSHIFT additive_expression'
pass
# additive-expression
def p_additive_expression_1(t):
'additive_expression : multiplicative_expression'
pass
def p_additive_expression_2(t):
'additive_expression : additive_expression PLUS multiplicative_expression'
pass
def p_additive_expression_3(t):
'additive_expression : additive_expression MINUS multiplicative_expression'
pass
# multiplicative-expression
def p_multiplicative_expression_1(t):
'multiplicative_expression : cast_expression'
pass
def p_multiplicative_expression_2(t):
'multiplicative_expression : multiplicative_expression TIMES cast_expression'
pass
def p_multiplicative_expression_3(t):
'multiplicative_expression : multiplicative_expression DIVIDE cast_expression'
pass
def p_multiplicative_expression_4(t):
'multiplicative_expression : multiplicative_expression MOD cast_expression'
pass
# cast-expression:
def p_cast_expression_1(t):
'cast_expression : unary_expression'
pass
def p_cast_expression_2(t):
'cast_expression : LPAREN type_name RPAREN cast_expression'
pass
# unary-expression:
def p_unary_expression_1(t):
'unary_expression : postfix_expression'
pass
def p_unary_expression_2(t):
'unary_expression : PLUSPLUS unary_expression'
pass
def p_unary_expression_3(t):
'unary_expression : MINUSMINUS unary_expression'
pass
def p_unary_expression_4(t):
'unary_expression : unary_operator cast_expression'
pass
def p_unary_expression_5(t):
'unary_expression : SIZEOF unary_expression'
pass
def p_unary_expression_6(t):
'unary_expression : SIZEOF LPAREN type_name RPAREN'
pass
#unary-operator
def p_unary_operator(t):
'''unary_operator : AND
| TIMES
| PLUS
| MINUS
| NOT
| LNOT '''
pass
# postfix-expression:
def p_postfix_expression_1(t):
'postfix_expression : primary_expression'
pass
def p_postfix_expression_2(t):
'postfix_expression : postfix_expression LBRACKET expression RBRACKET'
pass
def p_postfix_expression_3(t):
'postfix_expression : postfix_expression LPAREN argument_expression_list RPAREN'
pass
def p_postfix_expression_4(t):
'postfix_expression : postfix_expression LPAREN RPAREN'
pass
def p_postfix_expression_5(t):
'postfix_expression : postfix_expression PERIOD ID'
pass
def p_postfix_expression_6(t):
'postfix_expression : postfix_expression ARROW ID'
pass
def p_postfix_expression_7(t):
'postfix_expression : postfix_expression PLUSPLUS'
pass
def p_postfix_expression_8(t):
'postfix_expression : postfix_expression MINUSMINUS'
pass
# primary-expression:
def p_primary_expression(t):
'''primary_expression : ID
| constant
| SCONST
| LPAREN expression RPAREN'''
pass
# argument-expression-list:
def p_argument_expression_list(t):
'''argument_expression_list : assignment_expression
| argument_expression_list COMMA assignment_expression'''
pass
# constant:
def p_constant(t):
'''constant : ICONST
| FCONST
| CCONST'''
pass
def p_empty(t):
'empty : '
pass
def p_error(t):
print "Whoa. We're hosed"
import profile
# Build the grammar
profile.run("yacc.yacc()")

View file

@ -0,0 +1,108 @@
# -----------------------------------------------------------------------------
# calc.py
#
# A simple calculator with variables. This is from O'Reilly's
# "Lex and Yacc", p. 63.
# -----------------------------------------------------------------------------
tokens = (
'NAME','NUMBER',
'PLUS','MINUS','TIMES','DIVIDE','EQUALS',
'LPAREN','RPAREN',
)
# Tokens
t_PLUS = r'\+'
t_MINUS = r'-'
t_TIMES = r'\*'
t_DIVIDE = r'/'
t_EQUALS = r'='
t_LPAREN = r'\('
t_RPAREN = r'\)'
t_NAME = r'[a-zA-Z_][a-zA-Z0-9_]*'
def t_NUMBER(t):
r'\d+'
try:
t.value = int(t.value)
except ValueError:
print "Integer value too large", t.value
t.value = 0
return t
t_ignore = " \t"
def t_newline(t):
r'\n+'
t.lineno += t.value.count("\n")
def t_error(t):
print "Illegal character '%s'" % t.value[0]
t.skip(1)
# Build the lexer
import lex
lex.lex()
# Parsing rules
precedence = (
('left','PLUS','MINUS'),
('left','TIMES','DIVIDE'),
('right','UMINUS'),
)
# dictionary of names
names = { }
def p_statement_assign(t):
'statement : NAME EQUALS expression'
names[t[1]] = t[3]
def p_statement_expr(t):
'statement : expression'
print t[1]
def p_expression_binop(t):
'''expression : expression PLUS expression
| expression MINUS expression
| expression TIMES expression
| expression DIVIDE expression'''
if t[2] == '+' : t[0] = t[1] + t[3]
elif t[2] == '-': t[0] = t[1] - t[3]
elif t[2] == '*': t[0] = t[1] * t[3]
elif t[2] == '/': t[0] = t[1] / t[3]
def p_expression_uminus(t):
'expression : MINUS expression %prec UMINUS'
t[0] = -t[2]
def p_expression_group(t):
'expression : LPAREN expression RPAREN'
t[0] = t[2]
def p_expression_number(t):
'expression : NUMBER'
t[0] = t[1]
def p_expression_name(t):
'expression : NAME'
try:
t[0] = names[t[1]]
except LookupError:
print "Undefined name '%s'" % t[1]
t[0] = 0
def p_error(t):
print "Syntax error at '%s'" % t.value
import yacc
yacc.yacc()
while 1:
try:
s = raw_input('calc > ')
except EOFError:
break
yacc.parse(s)

View file

@ -0,0 +1,44 @@
# -----------------------------------------------------------------------------
# hedit.py
#
# Paring of Fortran H Edit descriptions (Contributed by Pearu Peterson)
#
# These tokens can't be easily tokenized because they are of the following
# form:
#
# nHc1...cn
#
# where n is a positive integer and c1 ... cn are characters.
#
# This example shows how to modify the state of the lexer to parse
# such tokens
# -----------------------------------------------------------------------------
tokens = (
'H_EDIT_DESCRIPTOR',
)
# Tokens
t_ignore = " \t\n"
def t_H_EDIT_DESCRIPTOR(t):
r"\d+H.*" # This grabs all of the remaining text
i = t.value.index('H')
n = eval(t.value[:i])
# Adjust the tokenizing position
t.lexer.lexpos -= len(t.value) - (i+1+n)
t.value = t.value[i+1:i+1+n]
return t
def t_error(t):
print "Illegal character '%s'" % t.value[0]
t.skip(1)
# Build the lexer
import lex
lex.lex()
lex.runmain()

View file

@ -0,0 +1,9 @@
An example showing how to use Python optimized mode.
To run:
- First run 'python calc.py'
- Then run 'python -OO calc.py'
If working corretly, the second version should run the
same way.

View file

@ -0,0 +1,110 @@
# -----------------------------------------------------------------------------
# calc.py
#
# A simple calculator with variables. This is from O'Reilly's
# "Lex and Yacc", p. 63.
# -----------------------------------------------------------------------------
tokens = (
'NAME','NUMBER',
'PLUS','MINUS','TIMES','DIVIDE','EQUALS',
'LPAREN','RPAREN',
)
# Tokens
t_PLUS = r'\+'
t_MINUS = r'-'
t_TIMES = r'\*'
t_DIVIDE = r'/'
t_EQUALS = r'='
t_LPAREN = r'\('
t_RPAREN = r'\)'
t_NAME = r'[a-zA-Z_][a-zA-Z0-9_]*'
def t_NUMBER(t):
r'\d+'
try:
t.value = int(t.value)
except ValueError:
print "Integer value too large", t.value
t.value = 0
return t
t_ignore = " \t"
def t_newline(t):
r'\n+'
t.lineno += t.value.count("\n")
def t_error(t):
print "Illegal character '%s'" % t.value[0]
t.skip(1)
# Build the lexer
import lex
lex.lex(optimize=1)
# Parsing rules
precedence = (
('left','PLUS','MINUS'),
('left','TIMES','DIVIDE'),
('right','UMINUS'),
)
# dictionary of names
names = { }
def p_statement_assign(t):
'statement : NAME EQUALS expression'
names[t[1]] = t[3]
def p_statement_expr(t):
'statement : expression'
print t[1]
def p_expression_binop(t):
'''expression : expression PLUS expression
| expression MINUS expression
| expression TIMES expression
| expression DIVIDE expression'''
if t[2] == '+' : t[0] = t[1] + t[3]
elif t[2] == '-': t[0] = t[1] - t[3]
elif t[2] == '*': t[0] = t[1] * t[3]
elif t[2] == '/': t[0] = t[1] / t[3]
elif t[2] == '<': t[0] = t[1] < t[3]
def p_expression_uminus(t):
'expression : MINUS expression %prec UMINUS'
t[0] = -t[2]
def p_expression_group(t):
'expression : LPAREN expression RPAREN'
t[0] = t[2]
def p_expression_number(t):
'expression : NUMBER'
t[0] = t[1]
def p_expression_name(t):
'expression : NAME'
try:
t[0] = names[t[1]]
except LookupError:
print "Undefined name '%s'" % t[1]
t[0] = 0
def p_error(t):
print "Syntax error at '%s'" % t.value
import yacc
yacc.yacc(optimize=1)
while 1:
try:
s = raw_input('calc > ')
except EOFError:
break
yacc.parse(s)

681
ext/ply/lex.py Normal file
View file

@ -0,0 +1,681 @@
#-----------------------------------------------------------------------------
# ply: lex.py
#
# Author: David M. Beazley (beazley@cs.uchicago.edu)
# Department of Computer Science
# University of Chicago
# Chicago, IL 60637
#
# Copyright (C) 2001, David M. Beazley
#
# $Header: /home/stever/bk/newmem2/ext/ply/lex.py 1.1 03/06/06 14:53:34-00:00 stever@ $
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# See the file COPYING for a complete copy of the LGPL.
#
#
# This module automatically constructs a lexical analysis module from regular
# expression rules defined in a user-defined module. The idea is essentially the same
# as that used in John Aycock's Spark framework, but the implementation works
# at the module level rather than requiring the use of classes.
#
# This module tries to provide an interface that is closely modeled after
# the traditional lex interface in Unix. It also differs from Spark
# in that:
#
# - It provides more extensive error checking and reporting if
# the user supplies a set of regular expressions that can't
# be compiled or if there is any other kind of a problem in
# the specification.
#
# - The interface is geared towards LALR(1) and LR(1) parser
# generators. That is tokens are generated one at a time
# rather than being generated in advanced all in one step.
#
# There are a few limitations of this module
#
# - The module interface makes it somewhat awkward to support more
# than one lexer at a time. Although somewhat inelegant from a
# design perspective, this is rarely a practical concern for
# most compiler projects.
#
# - The lexer requires that the entire input text be read into
# a string before scanning. I suppose that most machines have
# enough memory to make this a minor issues, but it makes
# the lexer somewhat difficult to use in interactive sessions
# or with streaming data.
#
#-----------------------------------------------------------------------------
r"""
lex.py
This module builds lex-like scanners based on regular expression rules.
To use the module, simply write a collection of regular expression rules
and actions like this:
# lexer.py
import lex
# Define a list of valid tokens
tokens = (
'IDENTIFIER', 'NUMBER', 'PLUS', 'MINUS'
)
# Define tokens as functions
def t_IDENTIFIER(t):
r' ([a-zA-Z_](\w|_)* '
return t
def t_NUMBER(t):
r' \d+ '
return t
# Some simple tokens with no actions
t_PLUS = r'\+'
t_MINUS = r'-'
# Initialize the lexer
lex.lex()
The tokens list is required and contains a complete list of all valid
token types that the lexer is allowed to produce. Token types are
restricted to be valid identifiers. This means that 'MINUS' is a valid
token type whereas '-' is not.
Rules are defined by writing a function with a name of the form
t_rulename. Each rule must accept a single argument which is
a token object generated by the lexer. This token has the following
attributes:
t.type = type string of the token. This is initially set to the
name of the rule without the leading t_
t.value = The value of the lexeme.
t.lineno = The value of the line number where the token was encountered
For example, the t_NUMBER() rule above might be called with the following:
t.type = 'NUMBER'
t.value = '42'
t.lineno = 3
Each rule returns the token object it would like to supply to the
parser. In most cases, the token t is returned with few, if any
modifications. To discard a token for things like whitespace or
comments, simply return nothing. For instance:
def t_whitespace(t):
r' \s+ '
pass
For faster lexing, you can also define this in terms of the ignore set like this:
t_ignore = ' \t'
The characters in this string are ignored by the lexer. Use of this feature can speed
up parsing significantly since scanning will immediately proceed to the next token.
lex requires that the token returned by each rule has an attribute
t.type. Other than this, rules are free to return any kind of token
object that they wish and may construct a new type of token object
from the attributes of t (provided the new object has the required
type attribute).
If illegal characters are encountered, the scanner executes the
function t_error(t) where t is a token representing the rest of the
string that hasn't been matched. If this function isn't defined, a
LexError exception is raised. The .text attribute of this exception
object contains the part of the string that wasn't matched.
The t.skip(n) method can be used to skip ahead n characters in the
input stream. This is usually only used in the error handling rule.
For instance, the following rule would print an error message and
continue:
def t_error(t):
print "Illegal character in input %s" % t.value[0]
t.skip(1)
Of course, a nice scanner might wish to skip more than one character
if the input looks very corrupted.
The lex module defines a t.lineno attribute on each token that can be used
to track the current line number in the input. The value of this
variable is not modified by lex so it is up to your lexer module
to correctly update its value depending on the lexical properties
of the input language. To do this, you might write rules such as
the following:
def t_newline(t):
r' \n+ '
t.lineno += t.value.count("\n")
To initialize your lexer so that it can be used, simply call the lex.lex()
function in your rule file. If there are any errors in your
specification, warning messages or an exception will be generated to
alert you to the problem.
(dave: this needs to be rewritten)
To use the newly constructed lexer from another module, simply do
this:
import lex
import lexer
plex.input("position = initial + rate*60")
while 1:
token = plex.token() # Get a token
if not token: break # No more tokens
... do whatever ...
Assuming that the module 'lexer' has initialized plex as shown
above, parsing modules can safely import 'plex' without having
to import the rule file or any additional imformation about the
scanner you have defined.
"""
# -----------------------------------------------------------------------------
__version__ = "1.3"
import re, types, sys, copy
# Exception thrown when invalid token encountered and no default
class LexError(Exception):
def __init__(self,message,s):
self.args = (message,)
self.text = s
# Token class
class LexToken:
def __str__(self):
return "LexToken(%s,%r,%d)" % (self.type,self.value,self.lineno)
def __repr__(self):
return str(self)
def skip(self,n):
try:
self._skipn += n
except AttributeError:
self._skipn = n
# -----------------------------------------------------------------------------
# Lexer class
#
# input() - Store a new string in the lexer
# token() - Get the next token
# -----------------------------------------------------------------------------
class Lexer:
def __init__(self):
self.lexre = None # Master regular expression
self.lexdata = None # Actual input data (as a string)
self.lexpos = 0 # Current position in input text
self.lexlen = 0 # Length of the input text
self.lexindexfunc = [ ] # Reverse mapping of groups to functions and types
self.lexerrorf = None # Error rule (if any)
self.lextokens = None # List of valid tokens
self.lexignore = None # Ignored characters
self.lineno = 1 # Current line number
self.debug = 0 # Debugging mode
self.optimize = 0 # Optimized mode
self.token = self.errtoken
def __copy__(self):
c = Lexer()
c.lexre = self.lexre
c.lexdata = self.lexdata
c.lexpos = self.lexpos
c.lexlen = self.lexlen
c.lenindexfunc = self.lexindexfunc
c.lexerrorf = self.lexerrorf
c.lextokens = self.lextokens
c.lexignore = self.lexignore
c.lineno = self.lineno
c.optimize = self.optimize
c.token = c.realtoken
# ------------------------------------------------------------
# input() - Push a new string into the lexer
# ------------------------------------------------------------
def input(self,s):
if not isinstance(s,types.StringType):
raise ValueError, "Expected a string"
self.lexdata = s
self.lexpos = 0
self.lexlen = len(s)
self.token = self.realtoken
# Change the token routine to point to realtoken()
global token
if token == self.errtoken:
token = self.token
# ------------------------------------------------------------
# errtoken() - Return error if token is called with no data
# ------------------------------------------------------------
def errtoken(self):
raise RuntimeError, "No input string given with input()"
# ------------------------------------------------------------
# token() - Return the next token from the Lexer
#
# Note: This function has been carefully implemented to be as fast
# as possible. Don't make changes unless you really know what
# you are doing
# ------------------------------------------------------------
def realtoken(self):
# Make local copies of frequently referenced attributes
lexpos = self.lexpos
lexlen = self.lexlen
lexignore = self.lexignore
lexdata = self.lexdata
while lexpos < lexlen:
# This code provides some short-circuit code for whitespace, tabs, and other ignored characters
if lexdata[lexpos] in lexignore:
lexpos += 1
continue
# Look for a regular expression match
m = self.lexre.match(lexdata,lexpos)
if m:
i = m.lastindex
lexpos = m.end()
tok = LexToken()
tok.value = m.group()
tok.lineno = self.lineno
tok.lexer = self
func,tok.type = self.lexindexfunc[i]
if not func:
self.lexpos = lexpos
return tok
# If token is processed by a function, call it
self.lexpos = lexpos
newtok = func(tok)
self.lineno = tok.lineno # Update line number
# Every function must return a token, if nothing, we just move to next token
if not newtok: continue
# Verify type of the token. If not in the token map, raise an error
if not self.optimize:
if not self.lextokens.has_key(newtok.type):
raise LexError, ("%s:%d: Rule '%s' returned an unknown token type '%s'" % (
func.func_code.co_filename, func.func_code.co_firstlineno,
func.__name__, newtok.type),lexdata[lexpos:])
return newtok
# No match. Call t_error() if defined.
if self.lexerrorf:
tok = LexToken()
tok.value = self.lexdata[lexpos:]
tok.lineno = self.lineno
tok.type = "error"
tok.lexer = self
oldpos = lexpos
newtok = self.lexerrorf(tok)
lexpos += getattr(tok,"_skipn",0)
if oldpos == lexpos:
# Error method didn't change text position at all. This is an error.
self.lexpos = lexpos
raise LexError, ("Scanning error. Illegal character '%s'" % (lexdata[lexpos]), lexdata[lexpos:])
if not newtok: continue
self.lexpos = lexpos
return newtok
self.lexpos = lexpos
raise LexError, ("No match found", lexdata[lexpos:])
# No more input data
self.lexpos = lexpos + 1
return None
# -----------------------------------------------------------------------------
# validate_file()
#
# This checks to see if there are duplicated t_rulename() functions or strings
# in the parser input file. This is done using a simple regular expression
# match on each line in the filename.
# -----------------------------------------------------------------------------
def validate_file(filename):
import os.path
base,ext = os.path.splitext(filename)
if ext != '.py': return 1 # No idea what the file is. Return OK
try:
f = open(filename)
lines = f.readlines()
f.close()
except IOError:
return 1 # Oh well
fre = re.compile(r'\s*def\s+(t_[a-zA-Z_0-9]*)\(')
sre = re.compile(r'\s*(t_[a-zA-Z_0-9]*)\s*=')
counthash = { }
linen = 1
noerror = 1
for l in lines:
m = fre.match(l)
if not m:
m = sre.match(l)
if m:
name = m.group(1)
prev = counthash.get(name)
if not prev:
counthash[name] = linen
else:
print "%s:%d: Rule %s redefined. Previously defined on line %d" % (filename,linen,name,prev)
noerror = 0
linen += 1
return noerror
# -----------------------------------------------------------------------------
# _read_lextab(module)
#
# Reads lexer table from a lextab file instead of using introspection.
# -----------------------------------------------------------------------------
def _read_lextab(lexer, fdict, module):
exec "import %s as lextab" % module
lexer.lexre = re.compile(lextab._lexre, re.VERBOSE)
lexer.lexindexfunc = lextab._lextab
for i in range(len(lextab._lextab)):
t = lexer.lexindexfunc[i]
if t:
if t[0]:
lexer.lexindexfunc[i] = (fdict[t[0]],t[1])
lexer.lextokens = lextab._lextokens
lexer.lexignore = lextab._lexignore
if lextab._lexerrorf:
lexer.lexerrorf = fdict[lextab._lexerrorf]
# -----------------------------------------------------------------------------
# lex(module)
#
# Build all of the regular expression rules from definitions in the supplied module
# -----------------------------------------------------------------------------
def lex(module=None,debug=0,optimize=0,lextab="lextab"):
ldict = None
regex = ""
error = 0
files = { }
lexer = Lexer()
lexer.debug = debug
lexer.optimize = optimize
global token,input
if module:
if not isinstance(module, types.ModuleType):
raise ValueError,"Expected a module"
ldict = module.__dict__
else:
# No module given. We might be able to get information from the caller.
try:
raise RuntimeError
except RuntimeError:
e,b,t = sys.exc_info()
f = t.tb_frame
f = f.f_back # Walk out to our calling function
ldict = f.f_globals # Grab its globals dictionary
if optimize and lextab:
try:
_read_lextab(lexer,ldict, lextab)
if not lexer.lexignore: lexer.lexignore = ""
token = lexer.token
input = lexer.input
return lexer
except ImportError:
pass
# Get the tokens map
tokens = ldict.get("tokens",None)
if not tokens:
raise SyntaxError,"lex: module does not define 'tokens'"
if not (isinstance(tokens,types.ListType) or isinstance(tokens,types.TupleType)):
raise SyntaxError,"lex: tokens must be a list or tuple."
# Build a dictionary of valid token names
lexer.lextokens = { }
if not optimize:
# Utility function for verifying tokens
def is_identifier(s):
for c in s:
if not (c.isalnum() or c == '_'): return 0
return 1
for n in tokens:
if not is_identifier(n):
print "lex: Bad token name '%s'" % n
error = 1
if lexer.lextokens.has_key(n):
print "lex: Warning. Token '%s' multiply defined." % n
lexer.lextokens[n] = None
else:
for n in tokens: lexer.lextokens[n] = None
if debug:
print "lex: tokens = '%s'" % lexer.lextokens.keys()
# Get a list of symbols with the t_ prefix
tsymbols = [f for f in ldict.keys() if f[:2] == 't_']
# Now build up a list of functions and a list of strings
fsymbols = [ ]
ssymbols = [ ]
for f in tsymbols:
if isinstance(ldict[f],types.FunctionType):
fsymbols.append(ldict[f])
elif isinstance(ldict[f],types.StringType):
ssymbols.append((f,ldict[f]))
else:
print "lex: %s not defined as a function or string" % f
error = 1
# Sort the functions by line number
fsymbols.sort(lambda x,y: cmp(x.func_code.co_firstlineno,y.func_code.co_firstlineno))
# Sort the strings by regular expression length
ssymbols.sort(lambda x,y: (len(x[1]) < len(y[1])) - (len(x[1]) > len(y[1])))
# Check for non-empty symbols
if len(fsymbols) == 0 and len(ssymbols) == 0:
raise SyntaxError,"lex: no rules of the form t_rulename are defined."
# Add all of the rules defined with actions first
for f in fsymbols:
line = f.func_code.co_firstlineno
file = f.func_code.co_filename
files[file] = None
if not optimize:
if f.func_code.co_argcount > 1:
print "%s:%d: Rule '%s' has too many arguments." % (file,line,f.__name__)
error = 1
continue
if f.func_code.co_argcount < 1:
print "%s:%d: Rule '%s' requires an argument." % (file,line,f.__name__)
error = 1
continue
if f.__name__ == 't_ignore':
print "%s:%d: Rule '%s' must be defined as a string." % (file,line,f.__name__)
error = 1
continue
if f.__name__ == 't_error':
lexer.lexerrorf = f
continue
if f.__doc__:
if not optimize:
try:
c = re.compile(f.__doc__, re.VERBOSE)
except re.error,e:
print "%s:%d: Invalid regular expression for rule '%s'. %s" % (file,line,f.__name__,e)
error = 1
continue
if debug:
print "lex: Adding rule %s -> '%s'" % (f.__name__,f.__doc__)
# Okay. The regular expression seemed okay. Let's append it to the master regular
# expression we're building
if (regex): regex += "|"
regex += "(?P<%s>%s)" % (f.__name__,f.__doc__)
else:
print "%s:%d: No regular expression defined for rule '%s'" % (file,line,f.__name__)
# Now add all of the simple rules
for name,r in ssymbols:
if name == 't_ignore':
lexer.lexignore = r
continue
if not optimize:
if name == 't_error':
raise SyntaxError,"lex: Rule 't_error' must be defined as a function"
error = 1
continue
if not lexer.lextokens.has_key(name[2:]):
print "lex: Rule '%s' defined for an unspecified token %s." % (name,name[2:])
error = 1
continue
try:
c = re.compile(r,re.VERBOSE)
except re.error,e:
print "lex: Invalid regular expression for rule '%s'. %s" % (name,e)
error = 1
continue
if debug:
print "lex: Adding rule %s -> '%s'" % (name,r)
if regex: regex += "|"
regex += "(?P<%s>%s)" % (name,r)
if not optimize:
for f in files.keys():
if not validate_file(f):
error = 1
try:
if debug:
print "lex: regex = '%s'" % regex
lexer.lexre = re.compile(regex, re.VERBOSE)
# Build the index to function map for the matching engine
lexer.lexindexfunc = [ None ] * (max(lexer.lexre.groupindex.values())+1)
for f,i in lexer.lexre.groupindex.items():
handle = ldict[f]
if isinstance(handle,types.FunctionType):
lexer.lexindexfunc[i] = (handle,handle.__name__[2:])
else:
# If rule was specified as a string, we build an anonymous
# callback function to carry out the action
lexer.lexindexfunc[i] = (None,f[2:])
# If a lextab was specified, we create a file containing the precomputed
# regular expression and index table
if lextab and optimize:
lt = open(lextab+".py","w")
lt.write("# %s.py. This file automatically created by PLY. Don't edit.\n" % lextab)
lt.write("_lexre = %s\n" % repr(regex))
lt.write("_lextab = [\n");
for i in range(0,len(lexer.lexindexfunc)):
t = lexer.lexindexfunc[i]
if t:
if t[0]:
lt.write(" ('%s',%s),\n"% (t[0].__name__, repr(t[1])))
else:
lt.write(" (None,%s),\n" % repr(t[1]))
else:
lt.write(" None,\n")
lt.write("]\n");
lt.write("_lextokens = %s\n" % repr(lexer.lextokens))
lt.write("_lexignore = %s\n" % repr(lexer.lexignore))
if (lexer.lexerrorf):
lt.write("_lexerrorf = %s\n" % repr(lexer.lexerrorf.__name__))
else:
lt.write("_lexerrorf = None\n")
lt.close()
except re.error,e:
print "lex: Fatal error. Unable to compile regular expression rules. %s" % e
error = 1
if error:
raise SyntaxError,"lex: Unable to build lexer."
if not lexer.lexerrorf:
print "lex: Warning. no t_error rule is defined."
if not lexer.lexignore: lexer.lexignore = ""
# Create global versions of the token() and input() functions
token = lexer.token
input = lexer.input
return lexer
# -----------------------------------------------------------------------------
# run()
#
# This runs the lexer as a main program
# -----------------------------------------------------------------------------
def runmain(lexer=None,data=None):
if not data:
try:
filename = sys.argv[1]
f = open(filename)
data = f.read()
f.close()
except IndexError:
print "Reading from standard input (type EOF to end):"
data = sys.stdin.read()
if lexer:
_input = lexer.input
else:
_input = input
_input(data)
if lexer:
_token = lexer.token
else:
_token = token
while 1:
tok = _token()
if not tok: break
print "(%s,'%s',%d)" % (tok.type, tok.value, tok.lineno)

9
ext/ply/test/README Normal file
View file

@ -0,0 +1,9 @@
This directory mostly contains tests for various types of error
conditions. To run:
$ python testlex.py .
$ python testyacc.py .
(make sure lex.py and yacc.py exist in this directory before
running the tests).

46
ext/ply/test/calclex.py Normal file
View file

@ -0,0 +1,46 @@
# -----------------------------------------------------------------------------
# calclex.py
# -----------------------------------------------------------------------------
tokens = (
'NAME','NUMBER',
'PLUS','MINUS','TIMES','DIVIDE','EQUALS',
'LPAREN','RPAREN',
)
# Tokens
t_PLUS = r'\+'
t_MINUS = r'-'
t_TIMES = r'\*'
t_DIVIDE = r'/'
t_EQUALS = r'='
t_LPAREN = r'\('
t_RPAREN = r'\)'
t_NAME = r'[a-zA-Z_][a-zA-Z0-9_]*'
def t_NUMBER(t):
r'\d+'
try:
t.value = int(t.value)
except ValueError:
print "Integer value too large", t.value
t.value = 0
return t
t_ignore = " \t"
def t_newline(t):
r'\n+'
t.lineno += t.value.count("\n")
def t_error(t):
print "Illegal character '%s'" % t.value[0]
t.skip(1)
# Build the lexer
import lex
lex.lex()

View file

@ -0,0 +1 @@
./lex_doc1.py:15: No regular expression defined for rule 't_NUMBER'

27
ext/ply/test/lex_doc1.py Normal file
View file

@ -0,0 +1,27 @@
# lex_token.py
#
# Missing documentation string
import lex
tokens = [
"PLUS",
"MINUS",
"NUMBER",
]
t_PLUS = r'\+'
t_MINUS = r'-'
def t_NUMBER(t):
pass
def t_error(t):
pass
import sys
sys.tracebacklimit = 0
lex.lex()

View file

@ -0,0 +1,2 @@
./lex_dup1.py:17: Rule t_NUMBER redefined. Previously defined on line 15
SyntaxError: lex: Unable to build lexer.

27
ext/ply/test/lex_dup1.py Normal file
View file

@ -0,0 +1,27 @@
# lex_token.py
#
# Duplicated rule specifiers
import lex
tokens = [
"PLUS",
"MINUS",
"NUMBER",
]
t_PLUS = r'\+'
t_MINUS = r'-'
t_NUMBER = r'\d+'
t_NUMBER = r'\d+'
def t_error(t):
pass
import sys
sys.tracebacklimit = 0
lex.lex()

View file

@ -0,0 +1,2 @@
./lex_dup2.py:19: Rule t_NUMBER redefined. Previously defined on line 15
SyntaxError: lex: Unable to build lexer.

31
ext/ply/test/lex_dup2.py Normal file
View file

@ -0,0 +1,31 @@
# lex_token.py
#
# Duplicated rule specifiers
import lex
tokens = [
"PLUS",
"MINUS",
"NUMBER",
]
t_PLUS = r'\+'
t_MINUS = r'-'
def t_NUMBER(t):
r'\d+'
pass
def t_NUMBER(t):
r'\d+'
pass
def t_error(t):
pass
import sys
sys.tracebacklimit = 0
lex.lex()

View file

@ -0,0 +1,2 @@
./lex_dup3.py:17: Rule t_NUMBER redefined. Previously defined on line 15
SyntaxError: lex: Unable to build lexer.

29
ext/ply/test/lex_dup3.py Normal file
View file

@ -0,0 +1,29 @@
# lex_token.py
#
# Duplicated rule specifiers
import lex
tokens = [
"PLUS",
"MINUS",
"NUMBER",
]
t_PLUS = r'\+'
t_MINUS = r'-'
t_NUMBER = r'\d+'
def t_NUMBER(t):
r'\d+'
pass
def t_error(t):
pass
import sys
sys.tracebacklimit = 0
lex.lex()

View file

@ -0,0 +1 @@
SyntaxError: lex: no rules of the form t_rulename are defined.

18
ext/ply/test/lex_empty.py Normal file
View file

@ -0,0 +1,18 @@
# lex_token.py
#
# No rules defined
import lex
tokens = [
"PLUS",
"MINUS",
"NUMBER",
]
import sys
sys.tracebacklimit = 0
lex.lex()

View file

@ -0,0 +1 @@
lex: Warning. no t_error rule is defined.

View file

@ -0,0 +1,22 @@
# lex_token.py
#
# Missing t_error() rule
import lex
tokens = [
"PLUS",
"MINUS",
"NUMBER",
]
t_PLUS = r'\+'
t_MINUS = r'-'
t_NUMBER = r'\d+'
import sys
sys.tracebacklimit = 0
lex.lex()

View file

@ -0,0 +1 @@
SyntaxError: lex: Rule 't_error' must be defined as a function

View file

@ -0,0 +1,24 @@
# lex_token.py
#
# t_error defined, but not function
import lex
tokens = [
"PLUS",
"MINUS",
"NUMBER",
]
t_PLUS = r'\+'
t_MINUS = r'-'
t_NUMBER = r'\d+'
t_error = "foo"
import sys
sys.tracebacklimit = 0
lex.lex()

View file

@ -0,0 +1,2 @@
./lex_error3.py:17: Rule 't_error' requires an argument.
SyntaxError: lex: Unable to build lexer.

View file

@ -0,0 +1,25 @@
# lex_token.py
#
# t_error defined as function, but with wrong # args
import lex
tokens = [
"PLUS",
"MINUS",
"NUMBER",
]
t_PLUS = r'\+'
t_MINUS = r'-'
t_NUMBER = r'\d+'
def t_error():
pass
import sys
sys.tracebacklimit = 0
lex.lex()

View file

@ -0,0 +1,2 @@
./lex_error4.py:17: Rule 't_error' has too many arguments.
SyntaxError: lex: Unable to build lexer.

View file

@ -0,0 +1,25 @@
# lex_token.py
#
# t_error defined as function, but too many args
import lex
tokens = [
"PLUS",
"MINUS",
"NUMBER",
]
t_PLUS = r'\+'
t_MINUS = r'-'
t_NUMBER = r'\d+'
def t_error(t,s):
pass
import sys
sys.tracebacklimit = 0
lex.lex()

View file

@ -0,0 +1,3 @@
(H_EDIT_DESCRIPTOR,'abc',1)
(H_EDIT_DESCRIPTOR,'abcdefghij',1)
(H_EDIT_DESCRIPTOR,'xy',1)

44
ext/ply/test/lex_hedit.py Normal file
View file

@ -0,0 +1,44 @@
# -----------------------------------------------------------------------------
# hedit.py
#
# Paring of Fortran H Edit descriptions (Contributed by Pearu Peterson)
#
# These tokens can't be easily tokenized because they are of the following
# form:
#
# nHc1...cn
#
# where n is a positive integer and c1 ... cn are characters.
#
# This example shows how to modify the state of the lexer to parse
# such tokens
# -----------------------------------------------------------------------------
tokens = (
'H_EDIT_DESCRIPTOR',
)
# Tokens
t_ignore = " \t\n"
def t_H_EDIT_DESCRIPTOR(t):
r"\d+H.*" # This grabs all of the remaining text
i = t.value.index('H')
n = eval(t.value[:i])
# Adjust the tokenizing position
t.lexer.lexpos -= len(t.value) - (i+1+n)
t.value = t.value[i+1:i+1+n]
return t
def t_error(t):
print "Illegal character '%s'" % t.value[0]
t.skip(1)
# Build the lexer
import lex
lex.lex()
lex.runmain(data="3Habc 10Habcdefghij 2Hxy")

View file

@ -0,0 +1,2 @@
./lex_ignore.py:17: Rule 't_ignore' must be defined as a string.
SyntaxError: lex: Unable to build lexer.

View file

@ -0,0 +1,29 @@
# lex_token.py
#
# Improperly specific ignore declaration
import lex
tokens = [
"PLUS",
"MINUS",
"NUMBER",
]
t_PLUS = r'\+'
t_MINUS = r'-'
t_NUMBER = r'\d+'
def t_ignore(t):
' \t'
pass
def t_error(t):
pass
import sys
sys.tracebacklimit = 0
lex.lex()

2
ext/ply/test/lex_re1.exp Normal file
View file

@ -0,0 +1,2 @@
lex: Invalid regular expression for rule 't_NUMBER'. unbalanced parenthesis
SyntaxError: lex: Unable to build lexer.

25
ext/ply/test/lex_re1.py Normal file
View file

@ -0,0 +1,25 @@
# lex_token.py
#
# Bad regular expression in a string
import lex
tokens = [
"PLUS",
"MINUS",
"NUMBER",
]
t_PLUS = r'\+'
t_MINUS = r'-'
t_NUMBER = r'(\d+'
def t_error(t):
pass
import sys
sys.tracebacklimit = 0
lex.lex()

View file

@ -0,0 +1,2 @@
lex: t_NUMBER not defined as a function or string
SyntaxError: lex: Unable to build lexer.

25
ext/ply/test/lex_rule1.py Normal file
View file

@ -0,0 +1,25 @@
# lex_token.py
#
# Rule defined as some other type
import lex
tokens = [
"PLUS",
"MINUS",
"NUMBER",
]
t_PLUS = r'\+'
t_MINUS = r'-'
t_NUMBER = 1
def t_error(t):
pass
import sys
sys.tracebacklimit = 0
lex.lex()

View file

@ -0,0 +1 @@
SyntaxError: lex: module does not define 'tokens'

View file

@ -0,0 +1,19 @@
# lex_token.py
#
# Tests for absence of tokens variable
import lex
t_PLUS = r'\+'
t_MINUS = r'-'
t_NUMBER = r'\d+'
def t_error(t):
pass
import sys
sys.tracebacklimit = 0
lex.lex()

View file

@ -0,0 +1 @@
SyntaxError: lex: tokens must be a list or tuple.

View file

@ -0,0 +1,21 @@
# lex_token.py
#
# Tests for tokens of wrong type
import lex
tokens = "PLUS MINUS NUMBER"
t_PLUS = r'\+'
t_MINUS = r'-'
t_NUMBER = r'\d+'
def t_error(t):
pass
import sys
sys.tracebacklimit = 0
lex.lex()

View file

@ -0,0 +1,2 @@
lex: Rule 't_MINUS' defined for an unspecified token MINUS.
SyntaxError: lex: Unable to build lexer.

View file

@ -0,0 +1,24 @@
# lex_token.py
#
# tokens is right type, but is missing a token for one rule
import lex
tokens = [
"PLUS",
"NUMBER",
]
t_PLUS = r'\+'
t_MINUS = r'-'
t_NUMBER = r'\d+'
def t_error(t):
pass
import sys
sys.tracebacklimit = 0
lex.lex()

View file

@ -0,0 +1,2 @@
lex: Bad token name '-'
SyntaxError: lex: Unable to build lexer.

View file

@ -0,0 +1,26 @@
# lex_token.py
#
# Bad token name
import lex
tokens = [
"PLUS",
"MINUS",
"-",
"NUMBER",
]
t_PLUS = r'\+'
t_MINUS = r'-'
t_NUMBER = r'\d+'
def t_error(t):
pass
import sys
sys.tracebacklimit = 0
lex.lex()

View file

@ -0,0 +1 @@
lex.LexError: ./lex_token5.py:16: Rule 't_NUMBER' returned an unknown token type 'NUM'

View file

@ -0,0 +1,31 @@
# lex_token.py
#
# Return a bad token name
import lex
tokens = [
"PLUS",
"MINUS",
"NUMBER",
]
t_PLUS = r'\+'
t_MINUS = r'-'
def t_NUMBER(t):
r'\d+'
t.type = "NUM"
return t
def t_error(t):
pass
import sys
sys.tracebacklimit = 0
lex.lex()
lex.input("1234")
t = lex.token()

57
ext/ply/test/testlex.py Executable file
View file

@ -0,0 +1,57 @@
#!/usr/local/bin
# ----------------------------------------------------------------------
# testlex.py
#
# Run tests for the lexing module
# ----------------------------------------------------------------------
import sys,os,glob
if len(sys.argv) < 2:
print "Usage: python testlex.py directory"
raise SystemExit
dirname = None
make = 0
for o in sys.argv[1:]:
if o == '-make':
make = 1
else:
dirname = o
break
if not dirname:
print "Usage: python testlex.py [-make] directory"
raise SystemExit
f = glob.glob("%s/%s" % (dirname,"lex_*.py"))
print "**** Running tests for lex ****"
for t in f:
name = t[:-3]
print "Testing %-32s" % name,
if make:
if not os.path.exists("%s.exp" % name):
os.system("python %s.py >%s.exp 2>&1" % (name,name))
passed = 1
else:
os.system("python %s.py >%s.out 2>&1" % (name,name))
a = os.system("diff %s.out %s.exp >%s.dif" % (name,name,name))
if a == 0:
passed = 1
else:
passed = 0
if passed:
print "Passed"
else:
print "Failed. See %s.dif" % name

58
ext/ply/test/testyacc.py Normal file
View file

@ -0,0 +1,58 @@
#!/usr/local/bin
# ----------------------------------------------------------------------
# testyacc.py
#
# Run tests for the yacc module
# ----------------------------------------------------------------------
import sys,os,glob
if len(sys.argv) < 2:
print "Usage: python testyacc.py directory"
raise SystemExit
dirname = None
make = 0
for o in sys.argv[1:]:
if o == '-make':
make = 1
else:
dirname = o
break
if not dirname:
print "Usage: python testyacc.py [-make] directory"
raise SystemExit
f = glob.glob("%s/%s" % (dirname,"yacc_*.py"))
print "**** Running tests for yacc ****"
for t in f:
name = t[:-3]
print "Testing %-32s" % name,
os.system("rm -f %s/parsetab.*" % dirname)
if make:
if not os.path.exists("%s.exp" % name):
os.system("python %s.py >%s.exp 2>&1" % (name,name))
passed = 1
else:
os.system("python %s.py >%s.out 2>&1" % (name,name))
a = os.system("diff %s.out %s.exp >%s.dif" % (name,name,name))
if a == 0:
passed = 1
else:
passed = 0
if passed:
print "Passed"
else:
print "Failed. See %s.dif" % name

View file

@ -0,0 +1,3 @@
./yacc_badargs.py:21: Rule 'p_statement_assign' has too many arguments.
./yacc_badargs.py:25: Rule 'p_statement_expr' requires an argument.
yacc.YaccError: Unable to construct parser.

View file

@ -0,0 +1,67 @@
# -----------------------------------------------------------------------------
# yacc_badargs.py
#
# Rules with wrong # args
# -----------------------------------------------------------------------------
import sys
sys.tracebacklimit = 0
from calclex import tokens
# Parsing rules
precedence = (
('left','PLUS','MINUS'),
('left','TIMES','DIVIDE'),
('right','UMINUS'),
)
# dictionary of names
names = { }
def p_statement_assign(t,s):
'statement : NAME EQUALS expression'
names[t[1]] = t[3]
def p_statement_expr():
'statement : expression'
print t[1]
def p_expression_binop(t):
'''expression : expression PLUS expression
| expression MINUS expression
| expression TIMES expression
| expression DIVIDE expression'''
if t[2] == '+' : t[0] = t[1] + t[3]
elif t[2] == '-': t[0] = t[1] - t[3]
elif t[2] == '*': t[0] = t[1] * t[3]
elif t[3] == '/': t[0] = t[1] / t[3]
def p_expression_uminus(t):
'expression : MINUS expression %prec UMINUS'
t[0] = -t[2]
def p_expression_group(t):
'expression : LPAREN expression RPAREN'
t[0] = t[2]
def p_expression_number(t):
'expression : NUMBER'
t[0] = t[1]
def p_expression_name(t):
'expression : NAME'
try:
t[0] = names[t[1]]
except LookupError:
print "Undefined name '%s'" % t[1]
t[0] = 0
def p_error(t):
print "Syntax error at '%s'" % t.value
import yacc
yacc.yacc()

View file

@ -0,0 +1 @@
yacc.YaccError: precedence must be a list or tuple.

View file

@ -0,0 +1,63 @@
# -----------------------------------------------------------------------------
# yacc_badprec.py
#
# Bad precedence specifier
# -----------------------------------------------------------------------------
import sys
sys.tracebacklimit = 0
from calclex import tokens
# Parsing rules
precedence = "blah"
# dictionary of names
names = { }
def p_statement_assign(t):
'statement : NAME EQUALS expression'
names[t[1]] = t[3]
def p_statement_expr(t):
'statement : expression'
print t[1]
def p_expression_binop(t):
'''expression : expression PLUS expression
| expression MINUS expression
| expression TIMES expression
| expression DIVIDE expression'''
if t[2] == '+' : t[0] = t[1] + t[3]
elif t[2] == '-': t[0] = t[1] - t[3]
elif t[2] == '*': t[0] = t[1] * t[3]
elif t[3] == '/': t[0] = t[1] / t[3]
def p_expression_uminus(t):
'expression : MINUS expression %prec UMINUS'
t[0] = -t[2]
def p_expression_group(t):
'expression : LPAREN expression RPAREN'
t[0] = t[2]
def p_expression_number(t):
'expression : NUMBER'
t[0] = t[1]
def p_expression_name(t):
'expression : NAME'
try:
t[0] = names[t[1]]
except LookupError:
print "Undefined name '%s'" % t[1]
t[0] = 0
def p_error(t):
print "Syntax error at '%s'" % t.value
import yacc
yacc.yacc()

View file

@ -0,0 +1,3 @@
yacc: Invalid precedence table.
yacc: Generating SLR parsing table...
yacc: 4 shift/reduce conflicts

View file

@ -0,0 +1,67 @@
# -----------------------------------------------------------------------------
# yacc_badprec2.py
#
# Bad precedence
# -----------------------------------------------------------------------------
import sys
sys.tracebacklimit = 0
from calclex import tokens
# Parsing rules
precedence = (
42,
('left','TIMES','DIVIDE'),
('right','UMINUS'),
)
# dictionary of names
names = { }
def p_statement_assign(t):
'statement : NAME EQUALS expression'
names[t[1]] = t[3]
def p_statement_expr(t):
'statement : expression'
print t[1]
def p_expression_binop(t):
'''expression : expression PLUS expression
| expression MINUS expression
| expression TIMES expression
| expression DIVIDE expression'''
if t[2] == '+' : t[0] = t[1] + t[3]
elif t[2] == '-': t[0] = t[1] - t[3]
elif t[2] == '*': t[0] = t[1] * t[3]
elif t[3] == '/': t[0] = t[1] / t[3]
def p_expression_uminus(t):
'expression : MINUS expression %prec UMINUS'
t[0] = -t[2]
def p_expression_group(t):
'expression : LPAREN expression RPAREN'
t[0] = t[2]
def p_expression_number(t):
'expression : NUMBER'
t[0] = t[1]
def p_expression_name(t):
'expression : NAME'
try:
t[0] = names[t[1]]
except LookupError:
print "Undefined name '%s'" % t[1]
t[0] = 0
def p_error(t):
print "Syntax error at '%s'" % t.value
import yacc
yacc.yacc()

View file

@ -0,0 +1,5 @@
./yacc_badrule.py:22: Syntax error. Expected ':'
./yacc_badrule.py:26: Syntax error in rule 'statement'
./yacc_badrule.py:31: Syntax error. Expected ':'
./yacc_badrule.py:40: Syntax error. Expected ':'
yacc.YaccError: Unable to construct parser.

View file

@ -0,0 +1,67 @@
# -----------------------------------------------------------------------------
# yacc_badrule.py
#
# Syntax problems in the rule strings
# -----------------------------------------------------------------------------
import sys
sys.tracebacklimit = 0
from calclex import tokens
# Parsing rules
precedence = (
('left','PLUS','MINUS'),
('left','TIMES','DIVIDE'),
('right','UMINUS'),
)
# dictionary of names
names = { }
def p_statement_assign(t):
'statement NAME EQUALS expression'
names[t[1]] = t[3]
def p_statement_expr(t):
'statement'
print t[1]
def p_expression_binop(t):
'''expression : expression PLUS expression
expression MINUS expression
| expression TIMES expression
| expression DIVIDE expression'''
if t[2] == '+' : t[0] = t[1] + t[3]
elif t[2] == '-': t[0] = t[1] - t[3]
elif t[2] == '*': t[0] = t[1] * t[3]
elif t[3] == '/': t[0] = t[1] / t[3]
def p_expression_uminus(t):
'expression: MINUS expression %prec UMINUS'
t[0] = -t[2]
def p_expression_group(t):
'expression : LPAREN expression RPAREN'
t[0] = t[2]
def p_expression_number(t):
'expression : NUMBER'
t[0] = t[1]
def p_expression_name(t):
'expression : NAME'
try:
t[0] = names[t[1]]
except LookupError:
print "Undefined name '%s'" % t[1]
t[0] = 0
def p_error(t):
print "Syntax error at '%s'" % t.value
import yacc
yacc.yacc()

View file

@ -0,0 +1 @@
yacc.YaccError: tokens must be a list or tuple.

View file

@ -0,0 +1,68 @@
# -----------------------------------------------------------------------------
# yacc_badtok.py
#
# A grammar, but tokens is a bad datatype
# -----------------------------------------------------------------------------
import sys
sys.tracebacklimit = 0
tokens = "Hello"
# Parsing rules
precedence = (
('left','PLUS','MINUS'),
('left','TIMES','DIVIDE'),
('right','UMINUS'),
)
# dictionary of names
names = { }
def p_statement_assign(t):
'statement : NAME EQUALS expression'
names[t[1]] = t[3]
def p_statement_expr(t):
'statement : expression'
print t[1]
def p_expression_binop(t):
'''expression : expression PLUS expression
| expression MINUS expression
| expression TIMES expression
| expression DIVIDE expression'''
if t[2] == '+' : t[0] = t[1] + t[3]
elif t[2] == '-': t[0] = t[1] - t[3]
elif t[2] == '*': t[0] = t[1] * t[3]
elif t[3] == '/': t[0] = t[1] / t[3]
def p_expression_uminus(t):
'expression : MINUS expression %prec UMINUS'
t[0] = -t[2]
def p_expression_group(t):
'expression : LPAREN expression RPAREN'
t[0] = t[2]
def p_expression_number(t):
'expression : NUMBER'
t[0] = t[1]
def p_expression_name(t):
'expression : NAME'
try:
t[0] = names[t[1]]
except LookupError:
print "Undefined name '%s'" % t[1]
t[0] = 0
def p_error(t):
print "Syntax error at '%s'" % t.value
import yacc
yacc.yacc()

View file

@ -0,0 +1,4 @@
./yacc_dup.py:25: Function p_statement redefined. Previously defined on line 21
yacc: Warning. Token 'EQUALS' defined, but not used.
yacc: Warning. There is 1 unused token.
yacc: Generating SLR parsing table...

67
ext/ply/test/yacc_dup.py Normal file
View file

@ -0,0 +1,67 @@
# -----------------------------------------------------------------------------
# yacc_dup.py
#
# Duplicated rule name
# -----------------------------------------------------------------------------
import sys
sys.tracebacklimit = 0
from calclex import tokens
# Parsing rules
precedence = (
('left','PLUS','MINUS'),
('left','TIMES','DIVIDE'),
('right','UMINUS'),
)
# dictionary of names
names = { }
def p_statement(t):
'statement : NAME EQUALS expression'
names[t[1]] = t[3]
def p_statement(t):
'statement : expression'
print t[1]
def p_expression_binop(t):
'''expression : expression PLUS expression
| expression MINUS expression
| expression TIMES expression
| expression DIVIDE expression'''
if t[2] == '+' : t[0] = t[1] + t[3]
elif t[2] == '-': t[0] = t[1] - t[3]
elif t[2] == '*': t[0] = t[1] * t[3]
elif t[3] == '/': t[0] = t[1] / t[3]
def p_expression_uminus(t):
'expression : MINUS expression %prec UMINUS'
t[0] = -t[2]
def p_expression_group(t):
'expression : LPAREN expression RPAREN'
t[0] = t[2]
def p_expression_number(t):
'expression : NUMBER'
t[0] = t[1]
def p_expression_name(t):
'expression : NAME'
try:
t[0] = names[t[1]]
except LookupError:
print "Undefined name '%s'" % t[1]
t[0] = 0
def p_error(t):
print "Syntax error at '%s'" % t.value
import yacc
yacc.yacc()

View file

@ -0,0 +1 @@
yacc.YaccError: ./yacc_error1.py:59: p_error() requires 1 argument.

View file

@ -0,0 +1,67 @@
# -----------------------------------------------------------------------------
# yacc_error1.py
#
# Bad p_error() function
# -----------------------------------------------------------------------------
import sys
sys.tracebacklimit = 0
from calclex import tokens
# Parsing rules
precedence = (
('left','PLUS','MINUS'),
('left','TIMES','DIVIDE'),
('right','UMINUS'),
)
# dictionary of names
names = { }
def p_statement_assign(t):
'statement : NAME EQUALS expression'
names[t[1]] = t[3]
def p_statement_expr(t):
'statement : expression'
print t[1]
def p_expression_binop(t):
'''expression : expression PLUS expression
| expression MINUS expression
| expression TIMES expression
| expression DIVIDE expression'''
if t[2] == '+' : t[0] = t[1] + t[3]
elif t[2] == '-': t[0] = t[1] - t[3]
elif t[2] == '*': t[0] = t[1] * t[3]
elif t[3] == '/': t[0] = t[1] / t[3]
def p_expression_uminus(t):
'expression : MINUS expression %prec UMINUS'
t[0] = -t[2]
def p_expression_group(t):
'expression : LPAREN expression RPAREN'
t[0] = t[2]
def p_expression_number(t):
'expression : NUMBER'
t[0] = t[1]
def p_expression_name(t):
'expression : NAME'
try:
t[0] = names[t[1]]
except LookupError:
print "Undefined name '%s'" % t[1]
t[0] = 0
def p_error(t,s):
print "Syntax error at '%s'" % t.value
import yacc
yacc.yacc()

View file

@ -0,0 +1 @@
yacc.YaccError: ./yacc_error2.py:59: p_error() requires 1 argument.

View file

@ -0,0 +1,67 @@
# -----------------------------------------------------------------------------
# yacc_error1.py
#
# Bad p_error() function
# -----------------------------------------------------------------------------
import sys
sys.tracebacklimit = 0
from calclex import tokens
# Parsing rules
precedence = (
('left','PLUS','MINUS'),
('left','TIMES','DIVIDE'),
('right','UMINUS'),
)
# dictionary of names
names = { }
def p_statement_assign(t):
'statement : NAME EQUALS expression'
names[t[1]] = t[3]
def p_statement_expr(t):
'statement : expression'
print t[1]
def p_expression_binop(t):
'''expression : expression PLUS expression
| expression MINUS expression
| expression TIMES expression
| expression DIVIDE expression'''
if t[2] == '+' : t[0] = t[1] + t[3]
elif t[2] == '-': t[0] = t[1] - t[3]
elif t[2] == '*': t[0] = t[1] * t[3]
elif t[3] == '/': t[0] = t[1] / t[3]
def p_expression_uminus(t):
'expression : MINUS expression %prec UMINUS'
t[0] = -t[2]
def p_expression_group(t):
'expression : LPAREN expression RPAREN'
t[0] = t[2]
def p_expression_number(t):
'expression : NUMBER'
t[0] = t[1]
def p_expression_name(t):
'expression : NAME'
try:
t[0] = names[t[1]]
except LookupError:
print "Undefined name '%s'" % t[1]
t[0] = 0
def p_error():
print "Syntax error at '%s'" % t.value
import yacc
yacc.yacc()

View file

@ -0,0 +1 @@
yacc.YaccError: 'p_error' defined, but is not a function.

View file

@ -0,0 +1,66 @@
# -----------------------------------------------------------------------------
# yacc_error1.py
#
# Bad p_error() function
# -----------------------------------------------------------------------------
import sys
sys.tracebacklimit = 0
from calclex import tokens
# Parsing rules
precedence = (
('left','PLUS','MINUS'),
('left','TIMES','DIVIDE'),
('right','UMINUS'),
)
# dictionary of names
names = { }
def p_statement_assign(t):
'statement : NAME EQUALS expression'
names[t[1]] = t[3]
def p_statement_expr(t):
'statement : expression'
print t[1]
def p_expression_binop(t):
'''expression : expression PLUS expression
| expression MINUS expression
| expression TIMES expression
| expression DIVIDE expression'''
if t[2] == '+' : t[0] = t[1] + t[3]
elif t[2] == '-': t[0] = t[1] - t[3]
elif t[2] == '*': t[0] = t[1] * t[3]
elif t[3] == '/': t[0] = t[1] / t[3]
def p_expression_uminus(t):
'expression : MINUS expression %prec UMINUS'
t[0] = -t[2]
def p_expression_group(t):
'expression : LPAREN expression RPAREN'
t[0] = t[2]
def p_expression_number(t):
'expression : NUMBER'
t[0] = t[1]
def p_expression_name(t):
'expression : NAME'
try:
t[0] = names[t[1]]
except LookupError:
print "Undefined name '%s'" % t[1]
t[0] = 0
p_error = "blah"
import yacc
yacc.yacc()

View file

@ -0,0 +1,5 @@
yacc: Warning. Token 'NUMBER' defined, but not used.
yacc: Warning. There is 1 unused token.
yacc: Infinite recursion detected for symbol 'statement'.
yacc: Infinite recursion detected for symbol 'expression'.
yacc.YaccError: Unable to construct parser.

55
ext/ply/test/yacc_inf.py Normal file
View file

@ -0,0 +1,55 @@
# -----------------------------------------------------------------------------
# yacc_inf.py
#
# Infinite recursion
# -----------------------------------------------------------------------------
import sys
sys.tracebacklimit = 0
from calclex import tokens
# Parsing rules
precedence = (
('left','PLUS','MINUS'),
('left','TIMES','DIVIDE'),
('right','UMINUS'),
)
# dictionary of names
names = { }
def p_statement_assign(t):
'statement : NAME EQUALS expression'
names[t[1]] = t[3]
def p_statement_expr(t):
'statement : expression'
print t[1]
def p_expression_binop(t):
'''expression : expression PLUS expression
| expression MINUS expression
| expression TIMES expression
| expression DIVIDE expression'''
if t[2] == '+' : t[0] = t[1] + t[3]
elif t[2] == '-': t[0] = t[1] - t[3]
elif t[2] == '*': t[0] = t[1] * t[3]
elif t[3] == '/': t[0] = t[1] / t[3]
def p_expression_uminus(t):
'expression : MINUS expression %prec UMINUS'
t[0] = -t[2]
def p_expression_group(t):
'expression : LPAREN expression RPAREN'
t[0] = t[2]
def p_error(t):
print "Syntax error at '%s'" % t.value
import yacc
yacc.yacc()

View file

@ -0,0 +1,2 @@
./yacc_missing1.py:22: Symbol 'location' used, but not defined as a token or a rule.
yacc.YaccError: Unable to construct parser.

View file

@ -0,0 +1,67 @@
# -----------------------------------------------------------------------------
# yacc_missing1.py
#
# Grammar with a missing rule
# -----------------------------------------------------------------------------
import sys
sys.tracebacklimit = 0
from calclex import tokens
# Parsing rules
precedence = (
('left','PLUS','MINUS'),
('left','TIMES','DIVIDE'),
('right','UMINUS'),
)
# dictionary of names
names = { }
def p_statement_assign(t):
'statement : location EQUALS expression'
names[t[1]] = t[3]
def p_statement_expr(t):
'statement : expression'
print t[1]
def p_expression_binop(t):
'''expression : expression PLUS expression
| expression MINUS expression
| expression TIMES expression
| expression DIVIDE expression'''
if t[2] == '+' : t[0] = t[1] + t[3]
elif t[2] == '-': t[0] = t[1] - t[3]
elif t[2] == '*': t[0] = t[1] * t[3]
elif t[3] == '/': t[0] = t[1] / t[3]
def p_expression_uminus(t):
'expression : MINUS expression %prec UMINUS'
t[0] = -t[2]
def p_expression_group(t):
'expression : LPAREN expression RPAREN'
t[0] = t[2]
def p_expression_number(t):
'expression : NUMBER'
t[0] = t[1]
def p_expression_name(t):
'expression : NAME'
try:
t[0] = names[t[1]]
except LookupError:
print "Undefined name '%s'" % t[1]
t[0] = 0
def p_error(t):
print "Syntax error at '%s'" % t.value
import yacc
yacc.yacc()

View file

@ -0,0 +1,2 @@
./yacc_nodoc.py:25: No documentation string specified in function 'p_statement_expr'
yacc: Generating SLR parsing table...

Some files were not shown because too many files have changed in this diff Show more