From 7e0f021a9aec35fd8e6725e87e3313b101d26f5e Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Sun, 27 Jan 2008 11:37:44 +0100 Subject: Initial import (2.0.2-6) --- reference/C/CONTRIB/Makefile.am | 6 + reference/C/CONTRIB/Makefile.in | 528 ++++ reference/C/CONTRIB/OR_PRACTICAL_C/01_1.c | 6 + reference/C/CONTRIB/OR_PRACTICAL_C/01_2.c | 6 + reference/C/CONTRIB/OR_PRACTICAL_C/02_1.c | 18 + reference/C/CONTRIB/OR_PRACTICAL_C/03_1.c | 5 + reference/C/CONTRIB/OR_PRACTICAL_C/03_2.c | 13 + reference/C/CONTRIB/OR_PRACTICAL_C/03_3.c | 11 + reference/C/CONTRIB/OR_PRACTICAL_C/03_4.c | 16 + reference/C/CONTRIB/OR_PRACTICAL_C/04_1.c | 19 + reference/C/CONTRIB/OR_PRACTICAL_C/04_2.c | 9 + reference/C/CONTRIB/OR_PRACTICAL_C/04_3.c | 20 + reference/C/CONTRIB/OR_PRACTICAL_C/04_4.c | 13 + reference/C/CONTRIB/OR_PRACTICAL_C/04_5.c | 22 + reference/C/CONTRIB/OR_PRACTICAL_C/04_6.c | 26 + reference/C/CONTRIB/OR_PRACTICAL_C/04_7.c | 13 + reference/C/CONTRIB/OR_PRACTICAL_C/05_1.c | 25 + reference/C/CONTRIB/OR_PRACTICAL_C/05_2.c | 25 + reference/C/CONTRIB/OR_PRACTICAL_C/05_3.c | 38 + reference/C/CONTRIB/OR_PRACTICAL_C/06_1.c | 25 + reference/C/CONTRIB/OR_PRACTICAL_C/06_2.c | 39 + reference/C/CONTRIB/OR_PRACTICAL_C/06_3.c | 66 + reference/C/CONTRIB/OR_PRACTICAL_C/07_1.c | 24 + reference/C/CONTRIB/OR_PRACTICAL_C/07_2.c | 20 + reference/C/CONTRIB/OR_PRACTICAL_C/07_3.c | 44 + reference/C/CONTRIB/OR_PRACTICAL_C/08_1.c | 15 + reference/C/CONTRIB/OR_PRACTICAL_C/08_2.c | 30 + reference/C/CONTRIB/OR_PRACTICAL_C/08_3.c | 7 + reference/C/CONTRIB/OR_PRACTICAL_C/09_1.c | 13 + reference/C/CONTRIB/OR_PRACTICAL_C/09_2.c | 15 + reference/C/CONTRIB/OR_PRACTICAL_C/09_3.c | 16 + reference/C/CONTRIB/OR_PRACTICAL_C/09_4.c | 13 + reference/C/CONTRIB/OR_PRACTICAL_C/09_5.c | 13 + reference/C/CONTRIB/OR_PRACTICAL_C/10_1.c | 46 + reference/C/CONTRIB/OR_PRACTICAL_C/11_1.c | 19 + reference/C/CONTRIB/OR_PRACTICAL_C/12_1.c | 18 + reference/C/CONTRIB/OR_PRACTICAL_C/12_2.c | 17 + reference/C/CONTRIB/OR_PRACTICAL_C/12_3.c | 15 + reference/C/CONTRIB/OR_PRACTICAL_C/12_4.c | 15 + reference/C/CONTRIB/OR_PRACTICAL_C/12_5.c | 16 + reference/C/CONTRIB/OR_PRACTICAL_C/12_6.c | 50 + reference/C/CONTRIB/OR_PRACTICAL_C/12_7.c | 65 + reference/C/CONTRIB/OR_PRACTICAL_C/12_8.c | 103 + reference/C/CONTRIB/OR_PRACTICAL_C/13_1.c | 30 + reference/C/CONTRIB/OR_PRACTICAL_C/13_2.c | 70 + reference/C/CONTRIB/OR_PRACTICAL_C/14_01.c | 70 + reference/C/CONTRIB/OR_PRACTICAL_C/14_02.c | 34 + reference/C/CONTRIB/OR_PRACTICAL_C/14_03.c | 52 + reference/C/CONTRIB/OR_PRACTICAL_C/14_04.c | 38 + reference/C/CONTRIB/OR_PRACTICAL_C/14_05.c | 63 + reference/C/CONTRIB/OR_PRACTICAL_C/14_06.c | 37 + reference/C/CONTRIB/OR_PRACTICAL_C/14_07.c | 76 + reference/C/CONTRIB/OR_PRACTICAL_C/14_08.c | 77 + reference/C/CONTRIB/OR_PRACTICAL_C/14_09.c | 12 + reference/C/CONTRIB/OR_PRACTICAL_C/14_10.c | 13 + reference/C/CONTRIB/OR_PRACTICAL_C/14_11.c | 16 + reference/C/CONTRIB/OR_PRACTICAL_C/14_12.c | 15 + reference/C/CONTRIB/OR_PRACTICAL_C/14_13.c | 15 + reference/C/CONTRIB/OR_PRACTICAL_C/14_14.c | 15 + reference/C/CONTRIB/OR_PRACTICAL_C/14_15.c | 15 + reference/C/CONTRIB/OR_PRACTICAL_C/14_16.c | 16 + reference/C/CONTRIB/OR_PRACTICAL_C/14_17.c | 16 + reference/C/CONTRIB/OR_PRACTICAL_C/14_18.c | 8 + reference/C/CONTRIB/OR_PRACTICAL_C/14_19.c | 7 + reference/C/CONTRIB/OR_PRACTICAL_C/15_1.c | 31 + reference/C/CONTRIB/OR_PRACTICAL_C/16_1.c | 6 + reference/C/CONTRIB/OR_PRACTICAL_C/16_2.c | 27 + reference/C/CONTRIB/OR_PRACTICAL_C/16_3.c | 159 ++ reference/C/CONTRIB/OR_PRACTICAL_C/17_1.c | 117 + reference/C/CONTRIB/OR_PRACTICAL_C/17_2.c | 142 + reference/C/CONTRIB/OR_PRACTICAL_C/HEADER.html | 10 + reference/C/CONTRIB/OR_PRACTICAL_C/Makefile.am | 6 + reference/C/CONTRIB/OR_PRACTICAL_C/Makefile.in | 412 +++ reference/C/CONTRIB/OR_PRACTICAL_C/font.h | 20 + reference/C/CONTRIB/OR_PRACTICAL_C/fonts.c | 65 + reference/C/CONTRIB/OR_PRACTICAL_C/gen.h | 25 + reference/C/CONTRIB/OR_PRACTICAL_C/macro.h | 26 + reference/C/CONTRIB/OR_PRACTICAL_C/macros.c | 418 +++ reference/C/CONTRIB/OR_PRACTICAL_C/makefile.tcc | 19 + reference/C/CONTRIB/OR_PRACTICAL_C/makefile.unix | 16 + reference/C/CONTRIB/OR_PRACTICAL_C/standard.mac | 100 + reference/C/CONTRIB/OR_PRACTICAL_C/symbol.c | 77 + reference/C/CONTRIB/OR_PRACTICAL_C/test.csh | 32 + reference/C/CONTRIB/OR_PRACTICAL_C/tlint.c | 123 + reference/C/CONTRIB/OR_PRACTICAL_C/troff.test | 36 + reference/C/CONTRIB/OR_USING_C/02.1.c | 49 + reference/C/CONTRIB/OR_USING_C/02.2.c | 44 + reference/C/CONTRIB/OR_USING_C/02.3.c | 50 + reference/C/CONTRIB/OR_USING_C/02.4.c | 23 + reference/C/CONTRIB/OR_USING_C/02.5.c | 69 + reference/C/CONTRIB/OR_USING_C/03.1.c | 60 + reference/C/CONTRIB/OR_USING_C/03.2.c | 67 + reference/C/CONTRIB/OR_USING_C/04.1.c | 44 + reference/C/CONTRIB/OR_USING_C/04.2.c | 34 + reference/C/CONTRIB/OR_USING_C/04.3.c | 183 ++ reference/C/CONTRIB/OR_USING_C/05.1.c | 102 + reference/C/CONTRIB/OR_USING_C/05.2.c | 101 + reference/C/CONTRIB/OR_USING_C/05.3.c | 61 + reference/C/CONTRIB/OR_USING_C/06.1.c | 58 + reference/C/CONTRIB/OR_USING_C/07.1.c | 21 + reference/C/CONTRIB/OR_USING_C/08.1.c | 13 + reference/C/CONTRIB/OR_USING_C/08.2.c | 36 + reference/C/CONTRIB/OR_USING_C/08.3.c | 42 + reference/C/CONTRIB/OR_USING_C/08.4.c | 47 + reference/C/CONTRIB/OR_USING_C/08.5.c | 85 + reference/C/CONTRIB/OR_USING_C/08.6.c | 33 + reference/C/CONTRIB/OR_USING_C/08.7.c | 108 + reference/C/CONTRIB/OR_USING_C/09.1.c | 95 + reference/C/CONTRIB/OR_USING_C/09.2.c | 52 + reference/C/CONTRIB/OR_USING_C/09.3.c | 87 + reference/C/CONTRIB/OR_USING_C/09.4.c | 91 + reference/C/CONTRIB/OR_USING_C/10.1.c | 39 + reference/C/CONTRIB/OR_USING_C/10.2.c | 37 + reference/C/CONTRIB/OR_USING_C/10.3.c | 26 + reference/C/CONTRIB/OR_USING_C/10.4.c | 32 + reference/C/CONTRIB/OR_USING_C/10.5.c | 132 + reference/C/CONTRIB/OR_USING_C/10.h | 34 + reference/C/CONTRIB/OR_USING_C/11.1.c | 91 + reference/C/CONTRIB/OR_USING_C/11.2.c | 109 + reference/C/CONTRIB/OR_USING_C/11.3.c | 63 + reference/C/CONTRIB/OR_USING_C/11.4.c | 65 + reference/C/CONTRIB/OR_USING_C/11.5.c | 59 + reference/C/CONTRIB/OR_USING_C/11.6.c | 53 + reference/C/CONTRIB/OR_USING_C/11.7.c | 55 + reference/C/CONTRIB/OR_USING_C/12.1.c | 112 + reference/C/CONTRIB/OR_USING_C/12.2.c | 126 + reference/C/CONTRIB/OR_USING_C/12.3.c | 93 + reference/C/CONTRIB/OR_USING_C/13.1.c | 254 ++ reference/C/CONTRIB/OR_USING_C/13.2.c | 267 ++ reference/C/CONTRIB/OR_USING_C/13.3.c | 118 + reference/C/CONTRIB/OR_USING_C/14.1.c | 29 + reference/C/CONTRIB/OR_USING_C/14.2.c | 75 + reference/C/CONTRIB/OR_USING_C/HEADER.html | 4 + reference/C/CONTRIB/OR_USING_C/Makefile.am | 5 + reference/C/CONTRIB/OR_USING_C/Makefile.in | 410 +++ reference/C/CONTRIB/OR_USING_C/a.1.c | 4 + reference/C/CONTRIB/OR_USING_C/a.2.c | 6 + reference/C/CONTRIB/OR_USING_C/a.3.c | 12 + reference/C/CONTRIB/OR_USING_C/a.4.c | 18 + reference/C/CONTRIB/OR_USING_C/a.5.c | 29 + reference/C/CONTRIB/OR_USING_C/a.6.c | 19 + reference/C/CONTRIB/OR_USING_C/a.7.c | 16 + reference/C/CONTRIB/OR_USING_C/b.1.c | 176 ++ reference/C/CONTRIB/OR_USING_C/c.1.c | 96 + reference/C/CONTRIB/OR_USING_C/d.1.c | 117 + reference/C/CONTRIB/OR_USING_C/dircom.c | 117 + reference/C/CONTRIB/OR_USING_C/e.1.c | 63 + reference/C/CONTRIB/OR_USING_C/nap.c | 63 + reference/C/CONTRIB/SAWTELL/Makefile.am | 5 + reference/C/CONTRIB/SAWTELL/Makefile.in | 410 +++ reference/C/CONTRIB/SAWTELL/c-lesson.1 | 177 ++ reference/C/CONTRIB/SAWTELL/c-lesson.2 | 233 ++ reference/C/CONTRIB/SAWTELL/c-lesson.3 | 629 +++++ reference/C/CONTRIB/SAWTELL/c-lesson.4 | 313 +++ reference/C/CONTRIB/SAWTELL/c-lesson.5 | 291 ++ reference/C/CONTRIB/SAWTELL/c-lesson.6 | 331 +++ reference/C/CONTRIB/SAWTELL/c-lesson.7 | 161 ++ reference/C/CONTRIB/SAWTELL/c-lesson.8 | 502 ++++ reference/C/CONTRIB/SAWTELL/c-lesson.9 | 433 +++ reference/C/CONTRIB/SAWTELL/intro.html | 24 + reference/C/CONTRIB/SNIP/2dlife.c | 111 + reference/C/CONTRIB/SNIP/8087_sav.asm | 73 + reference/C/CONTRIB/SNIP/HEADER.html | 14 + reference/C/CONTRIB/SNIP/Makefile.am | 9 + reference/C/CONTRIB/SNIP/Makefile.in | 415 +++ reference/C/CONTRIB/SNIP/a2e.c | 51 + reference/C/CONTRIB/SNIP/absdisk.asm | 72 + reference/C/CONTRIB/SNIP/absdiskc.c | 34 + reference/C/CONTRIB/SNIP/addhndls.c | 104 + reference/C/CONTRIB/SNIP/addpath.c | 101 + reference/C/CONTRIB/SNIP/amalloc.c | 124 + reference/C/CONTRIB/SNIP/ansiflen.c | 34 + reference/C/CONTRIB/SNIP/ansiload.c | 66 + reference/C/CONTRIB/SNIP/ansiscrn.h | 72 + reference/C/CONTRIB/SNIP/ansiself.c | 10 + reference/C/CONTRIB/SNIP/ansisys.c | 60 + reference/C/CONTRIB/SNIP/ansisys.txt | 226 ++ reference/C/CONTRIB/SNIP/approx.c | 168 ++ reference/C/CONTRIB/SNIP/assignpr.c | 56 + reference/C/CONTRIB/SNIP/atr2ansi.c | 80 + reference/C/CONTRIB/SNIP/bascnvrt.c | 49 + reference/C/CONTRIB/SNIP/bastrngs.c | 144 + reference/C/CONTRIB/SNIP/big_mall.h | 15 + reference/C/CONTRIB/SNIP/bigfac.c | 122 + reference/C/CONTRIB/SNIP/bincomp.c | 172 ++ reference/C/CONTRIB/SNIP/biport.c | 16 + reference/C/CONTRIB/SNIP/biport.h | 34 + reference/C/CONTRIB/SNIP/bitarray.c | 15 + reference/C/CONTRIB/SNIP/bitcnt_1.c | 41 + reference/C/CONTRIB/SNIP/bitcnt_2.c | 33 + reference/C/CONTRIB/SNIP/bitfiles.c | 138 + reference/C/CONTRIB/SNIP/bitops.c | 13 + reference/C/CONTRIB/SNIP/bitstrng.c | 59 + reference/C/CONTRIB/SNIP/bmhasrch.c | 104 + reference/C/CONTRIB/SNIP/bmhisrch.c | 94 + reference/C/CONTRIB/SNIP/bmhsrch.c | 68 + reference/C/CONTRIB/SNIP/bordcolr.c | 109 + reference/C/CONTRIB/SNIP/break.c | 29 + reference/C/CONTRIB/SNIP/bresnham.c | 155 ++ reference/C/CONTRIB/SNIP/bstr_i.c | 40 + reference/C/CONTRIB/SNIP/c_cmnt.c | 154 ++ reference/C/CONTRIB/SNIP/c_lines.awk | 43 + reference/C/CONTRIB/SNIP/c_port.txt | 340 +++ reference/C/CONTRIB/SNIP/c_prec.txt | 74 + reference/C/CONTRIB/SNIP/cal.c | 144 + reference/C/CONTRIB/SNIP/calsupp.c | 65 + reference/C/CONTRIB/SNIP/cant.c | 22 + reference/C/CONTRIB/SNIP/cast.h | 23 + reference/C/CONTRIB/SNIP/cbtrap.asm | 63 + reference/C/CONTRIB/SNIP/ccomcall.c | 36 + reference/C/CONTRIB/SNIP/cctrap.asm | 64 + reference/C/CONTRIB/SNIP/cdir.c | 127 + reference/C/CONTRIB/SNIP/center.c | 49 + reference/C/CONTRIB/SNIP/cerrinst.asm | 100 + reference/C/CONTRIB/SNIP/cerrtrap.asm | 134 + reference/C/CONTRIB/SNIP/changprn.c | 52 + reference/C/CONTRIB/SNIP/chbytes.c | 203 ++ reference/C/CONTRIB/SNIP/checkexe.c | 126 + reference/C/CONTRIB/SNIP/checksum.c | 39 + reference/C/CONTRIB/SNIP/chgext.c | 71 + reference/C/CONTRIB/SNIP/chmod.c | 224 ++ reference/C/CONTRIB/SNIP/clock.c | 200 ++ reference/C/CONTRIB/SNIP/cmdline.c | 28 + reference/C/CONTRIB/SNIP/coldboot.asm | 42 + reference/C/CONTRIB/SNIP/combin.c | 66 + reference/C/CONTRIB/SNIP/commafmt.c | 82 + reference/C/CONTRIB/SNIP/commconv.c | 97 + reference/C/CONTRIB/SNIP/compiler.c | 46 + reference/C/CONTRIB/SNIP/cpucheck.asm | 78 + reference/C/CONTRIB/SNIP/crc-16.c | 37 + reference/C/CONTRIB/SNIP/crc-16f.c | 130 + reference/C/CONTRIB/SNIP/crc_32.c | 172 ++ reference/C/CONTRIB/SNIP/crypt.c | 98 + reference/C/CONTRIB/SNIP/ctrlprnt.c | 40 + reference/C/CONTRIB/SNIP/cubic.c | 61 + reference/C/CONTRIB/SNIP/cursize.c | 66 + reference/C/CONTRIB/SNIP/cursor.c | 52 + reference/C/CONTRIB/SNIP/daynum.c | 104 + reference/C/CONTRIB/SNIP/dbl2long.c | 64 + reference/C/CONTRIB/SNIP/dblround.c | 35 + reference/C/CONTRIB/SNIP/dd_struc.h | 31 + reference/C/CONTRIB/SNIP/dirent.h | 97 + reference/C/CONTRIB/SNIP/dirmask.c | 73 + reference/C/CONTRIB/SNIP/do.c | 17 + reference/C/CONTRIB/SNIP/doansi.h | 33 + reference/C/CONTRIB/SNIP/doansi_1.c | 478 ++++ reference/C/CONTRIB/SNIP/doansi_2.c | 229 ++ reference/C/CONTRIB/SNIP/dos5boot.h | 40 + reference/C/CONTRIB/SNIP/doscopy.c | 58 + reference/C/CONTRIB/SNIP/dosfuncs.txt | 34 + reference/C/CONTRIB/SNIP/dossort.c | 118 + reference/C/CONTRIB/SNIP/drivsrch.c | 84 + reference/C/CONTRIB/SNIP/droptime.c | 21 + reference/C/CONTRIB/SNIP/drvalid.c | 166 ++ reference/C/CONTRIB/SNIP/drvs.c | 43 + reference/C/CONTRIB/SNIP/dspclock.c | 83 + reference/C/CONTRIB/SNIP/dspdtst.c | 149 + reference/C/CONTRIB/SNIP/editgets.c | 371 +++ reference/C/CONTRIB/SNIP/eng.c | 50 + reference/C/CONTRIB/SNIP/enums.txt | 55 + reference/C/CONTRIB/SNIP/environ.txt | 63 + reference/C/CONTRIB/SNIP/errfix.c | 52 + reference/C/CONTRIB/SNIP/eval.c | 314 +++ reference/C/CONTRIB/SNIP/evsavres.txt | 5 + reference/C/CONTRIB/SNIP/except.doc | 184 ++ reference/C/CONTRIB/SNIP/ext_keys.c | 56 + reference/C/CONTRIB/SNIP/ext_keys.h | 98 + reference/C/CONTRIB/SNIP/factor.c | 80 + reference/C/CONTRIB/SNIP/factoryl.c | 103 + reference/C/CONTRIB/SNIP/faskbhit.c | 28 + reference/C/CONTRIB/SNIP/favail.c | 54 + reference/C/CONTRIB/SNIP/fcompare.c | 59 + reference/C/CONTRIB/SNIP/fcopy.c | 55 + reference/C/CONTRIB/SNIP/ferrorf.c | 25 + reference/C/CONTRIB/SNIP/filcount.c | 93 + reference/C/CONTRIB/SNIP/file_id.diz | 6 + reference/C/CONTRIB/SNIP/files.c | 93 + reference/C/CONTRIB/SNIP/fln_fix.c | 142 + reference/C/CONTRIB/SNIP/flnorm.c | 158 ++ reference/C/CONTRIB/SNIP/flopcopy.c | 120 + reference/C/CONTRIB/SNIP/fmemops.c | 52 + reference/C/CONTRIB/SNIP/fmtmoney.c | 119 + reference/C/CONTRIB/SNIP/fndislot.c | 48 + reference/C/CONTRIB/SNIP/format.c | 56 + reference/C/CONTRIB/SNIP/fpswitch.c | 81 + reference/C/CONTRIB/SNIP/fraction.c | 91 + reference/C/CONTRIB/SNIP/fscanbin.c | 115 + reference/C/CONTRIB/SNIP/fsize.c | 78 + reference/C/CONTRIB/SNIP/fsm.c | 37 + reference/C/CONTRIB/SNIP/ftime.c | 58 + reference/C/CONTRIB/SNIP/ftime.h | 20 + reference/C/CONTRIB/SNIP/getcmt.c | 267 ++ reference/C/CONTRIB/SNIP/getdcwd.c | 74 + reference/C/CONTRIB/SNIP/getkey.c | 27 + reference/C/CONTRIB/SNIP/getopt3.c | 102 + reference/C/CONTRIB/SNIP/getopts.c | 193 ++ reference/C/CONTRIB/SNIP/getopts.h | 31 + reference/C/CONTRIB/SNIP/getseg.c | 49 + reference/C/CONTRIB/SNIP/getstrng.c | 66 + reference/C/CONTRIB/SNIP/getvol.c | 68 + reference/C/CONTRIB/SNIP/glbl_env.c | 364 +++ reference/C/CONTRIB/SNIP/grafline.c | 29 + reference/C/CONTRIB/SNIP/grep.c | 567 ++++ reference/C/CONTRIB/SNIP/head.c | 40 + reference/C/CONTRIB/SNIP/hexdump.c | 88 + reference/C/CONTRIB/SNIP/hexorint.c | 54 + reference/C/CONTRIB/SNIP/hilobyte.h | 2 + reference/C/CONTRIB/SNIP/hires.asm | 37 + reference/C/CONTRIB/SNIP/howdy.c | 21 + reference/C/CONTRIB/SNIP/hstr_i.c | 48 + reference/C/CONTRIB/SNIP/hugeread.c | 242 ++ reference/C/CONTRIB/SNIP/hugesort.c | 105 + reference/C/CONTRIB/SNIP/ifactor.c | 66 + reference/C/CONTRIB/SNIP/inchcvrt.c | 79 + reference/C/CONTRIB/SNIP/initvars.c | 139 + reference/C/CONTRIB/SNIP/int2e.asm | 55 + reference/C/CONTRIB/SNIP/iostutor.txt | 260 ++ reference/C/CONTRIB/SNIP/iscons.c | 39 + reference/C/CONTRIB/SNIP/isfopen.c | 41 + reference/C/CONTRIB/SNIP/isisbn.c | 25 + reference/C/CONTRIB/SNIP/isnetdr.c | 45 + reference/C/CONTRIB/SNIP/ispow2.c | 12 + reference/C/CONTRIB/SNIP/isqrt.c | 91 + reference/C/CONTRIB/SNIP/isramdsk.c | 56 + reference/C/CONTRIB/SNIP/isshare.c | 86 + reference/C/CONTRIB/SNIP/isshift.c | 24 + reference/C/CONTRIB/SNIP/iswprot.c | 82 + reference/C/CONTRIB/SNIP/isxkbrd.c | 47 + reference/C/CONTRIB/SNIP/jdn.c | 124 + reference/C/CONTRIB/SNIP/jgrep.c | 178 ++ reference/C/CONTRIB/SNIP/joystick.c | 74 + reference/C/CONTRIB/SNIP/kb_data.c | 50 + reference/C/CONTRIB/SNIP/kbflip.c | 86 + reference/C/CONTRIB/SNIP/keylocks.c | 21 + reference/C/CONTRIB/SNIP/keywatch.c | 155 ++ reference/C/CONTRIB/SNIP/killff.c | 123 + reference/C/CONTRIB/SNIP/lbitops.c | 46 + reference/C/CONTRIB/SNIP/ldfloor.c | 41 + reference/C/CONTRIB/SNIP/ll_msort.c | 77 + reference/C/CONTRIB/SNIP/ll_qsort.c | 146 + reference/C/CONTRIB/SNIP/log.c | 216 ++ reference/C/CONTRIB/SNIP/lsary.c | 112 + reference/C/CONTRIB/SNIP/lsd.c | 265 ++ reference/C/CONTRIB/SNIP/ltoa.c | 58 + reference/C/CONTRIB/SNIP/ltostr.c | 57 + reference/C/CONTRIB/SNIP/lv1ws.c | 36 + reference/C/CONTRIB/SNIP/lzhuf.c | 646 +++++ reference/C/CONTRIB/SNIP/mainmain.c | 1 + reference/C/CONTRIB/SNIP/make.ini | 190 ++ reference/C/CONTRIB/SNIP/match.c | 585 ++++ reference/C/CONTRIB/SNIP/match.doc | 126 + reference/C/CONTRIB/SNIP/match.h | 107 + reference/C/CONTRIB/SNIP/maze_1.c | 183 ++ reference/C/CONTRIB/SNIP/maze_2.c | 1 + reference/C/CONTRIB/SNIP/maze_3.c | 7 + reference/C/CONTRIB/SNIP/mcb_env.c | 166 ++ reference/C/CONTRIB/SNIP/mdalloc.c | 160 ++ reference/C/CONTRIB/SNIP/mem.c | 681 +++++ reference/C/CONTRIB/SNIP/mem.h | 212 ++ reference/C/CONTRIB/SNIP/mem.txt | 215 ++ reference/C/CONTRIB/SNIP/memavail.c | 32 + reference/C/CONTRIB/SNIP/memrev.c | 52 + reference/C/CONTRIB/SNIP/missing.txt | 21 + reference/C/CONTRIB/SNIP/mkdirs.c | 52 + reference/C/CONTRIB/SNIP/mktone.c | 52 + reference/C/CONTRIB/SNIP/moon_age.c | 66 + reference/C/CONTRIB/SNIP/morse.c | 238 ++ reference/C/CONTRIB/SNIP/mouse.c | 352 +++ reference/C/CONTRIB/SNIP/mouse.h | 38 + reference/C/CONTRIB/SNIP/msb2ieee.c | 59 + reference/C/CONTRIB/SNIP/msc_peek.c | 48 + reference/C/CONTRIB/SNIP/mterm.c | 133 + reference/C/CONTRIB/SNIP/mv.c | 136 + reference/C/CONTRIB/SNIP/myio.cpp | 127 + reference/C/CONTRIB/SNIP/myio.h | 98 + reference/C/CONTRIB/SNIP/myio.mak | 107 + reference/C/CONTRIB/SNIP/myiodemo.cpp | 168 ++ reference/C/CONTRIB/SNIP/myline.cpp | 76 + reference/C/CONTRIB/SNIP/myline.h | 43 + reference/C/CONTRIB/SNIP/mystream.cpp | 142 + reference/C/CONTRIB/SNIP/mystream.h | 92 + reference/C/CONTRIB/SNIP/ndpcheck.asm | 44 + reference/C/CONTRIB/SNIP/noctrlc.c | 63 + reference/C/CONTRIB/SNIP/nonmsdos.txt | 42 + reference/C/CONTRIB/SNIP/noreset.c | 103 + reference/C/CONTRIB/SNIP/ord_text.c | 33 + reference/C/CONTRIB/SNIP/os_id.c | 134 + reference/C/CONTRIB/SNIP/os_id.h | 41 + reference/C/CONTRIB/SNIP/palndrom.c | 2 + reference/C/CONTRIB/SNIP/patmat.c | 75 + reference/C/CONTRIB/SNIP/pbmsrch.c | 95 + reference/C/CONTRIB/SNIP/pcnvrt.c | 22 + reference/C/CONTRIB/SNIP/pdn.lst | 184 ++ reference/C/CONTRIB/SNIP/perm_idx.c | 37 + reference/C/CONTRIB/SNIP/permute1.c | 114 + reference/C/CONTRIB/SNIP/permute2.c | 79 + reference/C/CONTRIB/SNIP/pfopen.c | 78 + reference/C/CONTRIB/SNIP/pi.c | 155 ++ reference/C/CONTRIB/SNIP/pi.h | 6 + reference/C/CONTRIB/SNIP/playdemo.c | 37 + reference/C/CONTRIB/SNIP/playlib.c | 137 + reference/C/CONTRIB/SNIP/pluraltx.c | 19 + reference/C/CONTRIB/SNIP/pmerge.c | 69 + reference/C/CONTRIB/SNIP/portable.h | 166 ++ reference/C/CONTRIB/SNIP/posix_ls.c | 83 + reference/C/CONTRIB/SNIP/posixdir.c | 276 ++ reference/C/CONTRIB/SNIP/pr.c | 301 ++ reference/C/CONTRIB/SNIP/printq.c | 46 + reference/C/CONTRIB/SNIP/prnspool.c | 151 ++ reference/C/CONTRIB/SNIP/prnspool.h | 48 + reference/C/CONTRIB/SNIP/prtoggle.c | 91 + reference/C/CONTRIB/SNIP/prtscrn.c | 53 + reference/C/CONTRIB/SNIP/prtstat.c | 68 + reference/C/CONTRIB/SNIP/psplit.c | 110 + reference/C/CONTRIB/SNIP/ptr_help.txt | 1117 ++++++++ reference/C/CONTRIB/SNIP/pushdir.c | 192 ++ reference/C/CONTRIB/SNIP/query.c | 51 + reference/C/CONTRIB/SNIP/rand1.c | 239 ++ reference/C/CONTRIB/SNIP/rand2.c | 51 + reference/C/CONTRIB/SNIP/rdxcnvrt.c | 49 + reference/C/CONTRIB/SNIP/read.me | 1 + reference/C/CONTRIB/SNIP/reboot.c | 32 + reference/C/CONTRIB/SNIP/redir.c | 59 + reference/C/CONTRIB/SNIP/remtab.c | 63 + reference/C/CONTRIB/SNIP/resource.lst | 459 ++++ reference/C/CONTRIB/SNIP/rfind1st.c | 156 ++ reference/C/CONTRIB/SNIP/rg_isort.c | 18 + reference/C/CONTRIB/SNIP/rg_qsort.c1 | 150 + reference/C/CONTRIB/SNIP/rg_qsort.c2 | 50 + reference/C/CONTRIB/SNIP/rg_rand.c | 88 + reference/C/CONTRIB/SNIP/rg_ssort.c | 43 + reference/C/CONTRIB/SNIP/rm_all.c | 222 ++ reference/C/CONTRIB/SNIP/rmallws.c | 28 + reference/C/CONTRIB/SNIP/rmlead.c | 26 + reference/C/CONTRIB/SNIP/rmtrail.c | 31 + reference/C/CONTRIB/SNIP/rndmize.c | 1 + reference/C/CONTRIB/SNIP/roman.c | 97 + reference/C/CONTRIB/SNIP/round.h | 11 + reference/C/CONTRIB/SNIP/rtlftrul.txt | 140 + reference/C/CONTRIB/SNIP/scaldate.c | 49 + reference/C/CONTRIB/SNIP/scaldate.h | 27 + reference/C/CONTRIB/SNIP/scanfrac.c | 119 + reference/C/CONTRIB/SNIP/scrnmacs.h | 92 + reference/C/CONTRIB/SNIP/scrnpick.c | 58 + reference/C/CONTRIB/SNIP/scrnsave.c | 79 + reference/C/CONTRIB/SNIP/scroll.c | 47 + reference/C/CONTRIB/SNIP/setenvar.c | 155 ++ reference/C/CONTRIB/SNIP/setimeto.c | 64 + reference/C/CONTRIB/SNIP/setvol.c | 222 ++ reference/C/CONTRIB/SNIP/sharing.txt | 70 + reference/C/CONTRIB/SNIP/shel2dos.c | 50 + reference/C/CONTRIB/SNIP/snippets._c_ | 42 + reference/C/CONTRIB/SNIP/snippets.ndx | 468 ++++ reference/C/CONTRIB/SNIP/snippets.txt | 23 + reference/C/CONTRIB/SNIP/snippets.wc | 373 +++ reference/C/CONTRIB/SNIP/sound.c | 30 + reference/C/CONTRIB/SNIP/sound.h | 181 ++ reference/C/CONTRIB/SNIP/soundex.c | 43 + reference/C/CONTRIB/SNIP/speed.c | 155 ++ reference/C/CONTRIB/SNIP/spin.c | 29 + reference/C/CONTRIB/SNIP/split.c | 71 + reference/C/CONTRIB/SNIP/srchfile.c | 225 ++ reference/C/CONTRIB/SNIP/sstrcpy.c | 13 + reference/C/CONTRIB/SNIP/stats.c | 53 + reference/C/CONTRIB/SNIP/storage.typ | 78 + reference/C/CONTRIB/SNIP/stptok.c | 38 + reference/C/CONTRIB/SNIP/str.cpp | 303 +++ reference/C/CONTRIB/SNIP/str.doc | 47 + reference/C/CONTRIB/SNIP/str.h | 322 +++ reference/C/CONTRIB/SNIP/str27seg.c | 148 + reference/C/CONTRIB/SNIP/strat.c | 170 ++ reference/C/CONTRIB/SNIP/strat.h | 22 + reference/C/CONTRIB/SNIP/strdup.c | 15 + reference/C/CONTRIB/SNIP/strecpy.asm | 92 + reference/C/CONTRIB/SNIP/strftime.c | 339 +++ reference/C/CONTRIB/SNIP/stripeof.c | 61 + reference/C/CONTRIB/SNIP/strrepl.c | 74 + reference/C/CONTRIB/SNIP/strrev.c | 37 + reference/C/CONTRIB/SNIP/strsort.c | 34 + reference/C/CONTRIB/SNIP/strucfil.c | 190 ++ reference/C/CONTRIB/SNIP/strupr.c | 29 + reference/C/CONTRIB/SNIP/stub.c | 115 + reference/C/CONTRIB/SNIP/style.c | 32 + reference/C/CONTRIB/SNIP/sunriset.c | 507 ++++ reference/C/CONTRIB/SNIP/tabtrick.c | 54 + reference/C/CONTRIB/SNIP/tail.c | 181 ++ reference/C/CONTRIB/SNIP/tasker.c | 127 + reference/C/CONTRIB/SNIP/tasker.h | 44 + reference/C/CONTRIB/SNIP/tasker.txt | 78 + reference/C/CONTRIB/SNIP/testcmt.c | 16 + reference/C/CONTRIB/SNIP/timegetc.c | 44 + reference/C/CONTRIB/SNIP/toascii.c | 37 + reference/C/CONTRIB/SNIP/todaybak.c | 98 + reference/C/CONTRIB/SNIP/toolkit.h | 66 + reference/C/CONTRIB/SNIP/touch.c | 63 + reference/C/CONTRIB/SNIP/tp6tod.c | 74 + reference/C/CONTRIB/SNIP/translat.c | 71 + reference/C/CONTRIB/SNIP/trapdemo.c | 74 + reference/C/CONTRIB/SNIP/trapflag.asm | 133 + reference/C/CONTRIB/SNIP/treedir.c | 53 + reference/C/CONTRIB/SNIP/trim.c | 78 + reference/C/CONTRIB/SNIP/truename.c | 103 + reference/C/CONTRIB/SNIP/uclock.c | 106 + reference/C/CONTRIB/SNIP/uclock.h | 53 + reference/C/CONTRIB/SNIP/unix2dos.c | 15 + reference/C/CONTRIB/SNIP/uudecode.c | 41 + reference/C/CONTRIB/SNIP/uuencode.c | 146 + reference/C/CONTRIB/SNIP/vfname.c | 226 ++ reference/C/CONTRIB/SNIP/video.c | 181 ++ reference/C/CONTRIB/SNIP/vidport.c | 114 + reference/C/CONTRIB/SNIP/vio.asm | 896 ++++++ reference/C/CONTRIB/SNIP/vio.h | 90 + reference/C/CONTRIB/SNIP/vt100.txt | 199 ++ reference/C/CONTRIB/SNIP/w_wrap.c | 139 + reference/C/CONTRIB/SNIP/w_wrap.h | 5 + reference/C/CONTRIB/SNIP/wb_fcopy.c | 86 + reference/C/CONTRIB/SNIP/wc.c | 66 + reference/C/CONTRIB/SNIP/weird.c | 13 + reference/C/CONTRIB/SNIP/where.c | 132 + reference/C/CONTRIB/SNIP/which_c.txt | 283 ++ reference/C/CONTRIB/SNIP/whicharc.c | 251 ++ reference/C/CONTRIB/SNIP/windchil.c | 19 + reference/C/CONTRIB/SNIP/wordwrap.c | 92 + reference/C/CONTRIB/SNIP/x00api.c | 411 +++ reference/C/CONTRIB/SNIP/x00api.h | 236 ++ reference/C/CONTRIB/SNIP/xfile.c | 200 ++ reference/C/CONTRIB/SNIP/xfile.h | 41 + reference/C/CONTRIB/SNIP/xstrcat.c | 32 + reference/C/CONTRIB/SNIP/xstrcmp.c | 67 + reference/C/CONTRIB/SNIP/xtest.c | 35 + reference/C/CONTRIB/YABL/Makefile.am | 5 + reference/C/CONTRIB/YABL/Makefile.in | 405 +++ reference/C/CONTRIB/YABL/yabl | 3161 ++++++++++++++++++++++ reference/C/CONTRIB/intro.html | 200 ++ 534 files changed, 55992 insertions(+) create mode 100644 reference/C/CONTRIB/Makefile.am create mode 100644 reference/C/CONTRIB/Makefile.in create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/01_1.c create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/01_2.c create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/02_1.c create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/03_1.c create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/03_2.c create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/03_3.c create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/03_4.c create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/04_1.c create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/04_2.c create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/04_3.c create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/04_4.c create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/04_5.c create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/04_6.c create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/04_7.c create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/05_1.c create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/05_2.c create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/05_3.c create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/06_1.c create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/06_2.c create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/06_3.c create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/07_1.c create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/07_2.c create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/07_3.c create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/08_1.c create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/08_2.c create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/08_3.c create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/09_1.c create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/09_2.c create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/09_3.c create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/09_4.c create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/09_5.c create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/10_1.c create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/11_1.c create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/12_1.c create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/12_2.c create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/12_3.c create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/12_4.c create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/12_5.c create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/12_6.c create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/12_7.c create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/12_8.c create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/13_1.c create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/13_2.c create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/14_01.c create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/14_02.c create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/14_03.c create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/14_04.c create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/14_05.c create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/14_06.c create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/14_07.c create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/14_08.c create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/14_09.c create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/14_10.c create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/14_11.c create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/14_12.c create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/14_13.c create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/14_14.c create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/14_15.c create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/14_16.c create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/14_17.c create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/14_18.c create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/14_19.c create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/15_1.c create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/16_1.c create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/16_2.c create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/16_3.c create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/17_1.c create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/17_2.c create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/HEADER.html create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/Makefile.am create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/Makefile.in create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/font.h create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/fonts.c create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/gen.h create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/macro.h create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/macros.c create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/makefile.tcc create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/makefile.unix create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/standard.mac create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/symbol.c create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/test.csh create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/tlint.c create mode 100644 reference/C/CONTRIB/OR_PRACTICAL_C/troff.test create mode 100644 reference/C/CONTRIB/OR_USING_C/02.1.c create mode 100644 reference/C/CONTRIB/OR_USING_C/02.2.c create mode 100644 reference/C/CONTRIB/OR_USING_C/02.3.c create mode 100644 reference/C/CONTRIB/OR_USING_C/02.4.c create mode 100644 reference/C/CONTRIB/OR_USING_C/02.5.c create mode 100644 reference/C/CONTRIB/OR_USING_C/03.1.c create mode 100644 reference/C/CONTRIB/OR_USING_C/03.2.c create mode 100644 reference/C/CONTRIB/OR_USING_C/04.1.c create mode 100644 reference/C/CONTRIB/OR_USING_C/04.2.c create mode 100644 reference/C/CONTRIB/OR_USING_C/04.3.c create mode 100644 reference/C/CONTRIB/OR_USING_C/05.1.c create mode 100644 reference/C/CONTRIB/OR_USING_C/05.2.c create mode 100644 reference/C/CONTRIB/OR_USING_C/05.3.c create mode 100644 reference/C/CONTRIB/OR_USING_C/06.1.c create mode 100644 reference/C/CONTRIB/OR_USING_C/07.1.c create mode 100644 reference/C/CONTRIB/OR_USING_C/08.1.c create mode 100644 reference/C/CONTRIB/OR_USING_C/08.2.c create mode 100644 reference/C/CONTRIB/OR_USING_C/08.3.c create mode 100644 reference/C/CONTRIB/OR_USING_C/08.4.c create mode 100644 reference/C/CONTRIB/OR_USING_C/08.5.c create mode 100644 reference/C/CONTRIB/OR_USING_C/08.6.c create mode 100644 reference/C/CONTRIB/OR_USING_C/08.7.c create mode 100644 reference/C/CONTRIB/OR_USING_C/09.1.c create mode 100644 reference/C/CONTRIB/OR_USING_C/09.2.c create mode 100644 reference/C/CONTRIB/OR_USING_C/09.3.c create mode 100644 reference/C/CONTRIB/OR_USING_C/09.4.c create mode 100644 reference/C/CONTRIB/OR_USING_C/10.1.c create mode 100644 reference/C/CONTRIB/OR_USING_C/10.2.c create mode 100644 reference/C/CONTRIB/OR_USING_C/10.3.c create mode 100644 reference/C/CONTRIB/OR_USING_C/10.4.c create mode 100644 reference/C/CONTRIB/OR_USING_C/10.5.c create mode 100644 reference/C/CONTRIB/OR_USING_C/10.h create mode 100644 reference/C/CONTRIB/OR_USING_C/11.1.c create mode 100644 reference/C/CONTRIB/OR_USING_C/11.2.c create mode 100644 reference/C/CONTRIB/OR_USING_C/11.3.c create mode 100644 reference/C/CONTRIB/OR_USING_C/11.4.c create mode 100644 reference/C/CONTRIB/OR_USING_C/11.5.c create mode 100644 reference/C/CONTRIB/OR_USING_C/11.6.c create mode 100644 reference/C/CONTRIB/OR_USING_C/11.7.c create mode 100644 reference/C/CONTRIB/OR_USING_C/12.1.c create mode 100644 reference/C/CONTRIB/OR_USING_C/12.2.c create mode 100644 reference/C/CONTRIB/OR_USING_C/12.3.c create mode 100644 reference/C/CONTRIB/OR_USING_C/13.1.c create mode 100644 reference/C/CONTRIB/OR_USING_C/13.2.c create mode 100644 reference/C/CONTRIB/OR_USING_C/13.3.c create mode 100644 reference/C/CONTRIB/OR_USING_C/14.1.c create mode 100644 reference/C/CONTRIB/OR_USING_C/14.2.c create mode 100644 reference/C/CONTRIB/OR_USING_C/HEADER.html create mode 100644 reference/C/CONTRIB/OR_USING_C/Makefile.am create mode 100644 reference/C/CONTRIB/OR_USING_C/Makefile.in create mode 100644 reference/C/CONTRIB/OR_USING_C/a.1.c create mode 100644 reference/C/CONTRIB/OR_USING_C/a.2.c create mode 100644 reference/C/CONTRIB/OR_USING_C/a.3.c create mode 100644 reference/C/CONTRIB/OR_USING_C/a.4.c create mode 100644 reference/C/CONTRIB/OR_USING_C/a.5.c create mode 100644 reference/C/CONTRIB/OR_USING_C/a.6.c create mode 100644 reference/C/CONTRIB/OR_USING_C/a.7.c create mode 100644 reference/C/CONTRIB/OR_USING_C/b.1.c create mode 100644 reference/C/CONTRIB/OR_USING_C/c.1.c create mode 100644 reference/C/CONTRIB/OR_USING_C/d.1.c create mode 100644 reference/C/CONTRIB/OR_USING_C/dircom.c create mode 100644 reference/C/CONTRIB/OR_USING_C/e.1.c create mode 100644 reference/C/CONTRIB/OR_USING_C/nap.c create mode 100644 reference/C/CONTRIB/SAWTELL/Makefile.am create mode 100644 reference/C/CONTRIB/SAWTELL/Makefile.in create mode 100755 reference/C/CONTRIB/SAWTELL/c-lesson.1 create mode 100755 reference/C/CONTRIB/SAWTELL/c-lesson.2 create mode 100755 reference/C/CONTRIB/SAWTELL/c-lesson.3 create mode 100755 reference/C/CONTRIB/SAWTELL/c-lesson.4 create mode 100755 reference/C/CONTRIB/SAWTELL/c-lesson.5 create mode 100755 reference/C/CONTRIB/SAWTELL/c-lesson.6 create mode 100755 reference/C/CONTRIB/SAWTELL/c-lesson.7 create mode 100755 reference/C/CONTRIB/SAWTELL/c-lesson.8 create mode 100755 reference/C/CONTRIB/SAWTELL/c-lesson.9 create mode 100644 reference/C/CONTRIB/SAWTELL/intro.html create mode 100755 reference/C/CONTRIB/SNIP/2dlife.c create mode 100755 reference/C/CONTRIB/SNIP/8087_sav.asm create mode 100644 reference/C/CONTRIB/SNIP/HEADER.html create mode 100644 reference/C/CONTRIB/SNIP/Makefile.am create mode 100644 reference/C/CONTRIB/SNIP/Makefile.in create mode 100755 reference/C/CONTRIB/SNIP/a2e.c create mode 100755 reference/C/CONTRIB/SNIP/absdisk.asm create mode 100755 reference/C/CONTRIB/SNIP/absdiskc.c create mode 100755 reference/C/CONTRIB/SNIP/addhndls.c create mode 100755 reference/C/CONTRIB/SNIP/addpath.c create mode 100755 reference/C/CONTRIB/SNIP/amalloc.c create mode 100755 reference/C/CONTRIB/SNIP/ansiflen.c create mode 100755 reference/C/CONTRIB/SNIP/ansiload.c create mode 100755 reference/C/CONTRIB/SNIP/ansiscrn.h create mode 100755 reference/C/CONTRIB/SNIP/ansiself.c create mode 100755 reference/C/CONTRIB/SNIP/ansisys.c create mode 100755 reference/C/CONTRIB/SNIP/ansisys.txt create mode 100755 reference/C/CONTRIB/SNIP/approx.c create mode 100755 reference/C/CONTRIB/SNIP/assignpr.c create mode 100755 reference/C/CONTRIB/SNIP/atr2ansi.c create mode 100755 reference/C/CONTRIB/SNIP/bascnvrt.c create mode 100755 reference/C/CONTRIB/SNIP/bastrngs.c create mode 100755 reference/C/CONTRIB/SNIP/big_mall.h create mode 100755 reference/C/CONTRIB/SNIP/bigfac.c create mode 100755 reference/C/CONTRIB/SNIP/bincomp.c create mode 100755 reference/C/CONTRIB/SNIP/biport.c create mode 100755 reference/C/CONTRIB/SNIP/biport.h create mode 100755 reference/C/CONTRIB/SNIP/bitarray.c create mode 100755 reference/C/CONTRIB/SNIP/bitcnt_1.c create mode 100755 reference/C/CONTRIB/SNIP/bitcnt_2.c create mode 100755 reference/C/CONTRIB/SNIP/bitfiles.c create mode 100755 reference/C/CONTRIB/SNIP/bitops.c create mode 100755 reference/C/CONTRIB/SNIP/bitstrng.c create mode 100755 reference/C/CONTRIB/SNIP/bmhasrch.c create mode 100755 reference/C/CONTRIB/SNIP/bmhisrch.c create mode 100755 reference/C/CONTRIB/SNIP/bmhsrch.c create mode 100755 reference/C/CONTRIB/SNIP/bordcolr.c create mode 100755 reference/C/CONTRIB/SNIP/break.c create mode 100755 reference/C/CONTRIB/SNIP/bresnham.c create mode 100755 reference/C/CONTRIB/SNIP/bstr_i.c create mode 100755 reference/C/CONTRIB/SNIP/c_cmnt.c create mode 100755 reference/C/CONTRIB/SNIP/c_lines.awk create mode 100755 reference/C/CONTRIB/SNIP/c_port.txt create mode 100755 reference/C/CONTRIB/SNIP/c_prec.txt create mode 100755 reference/C/CONTRIB/SNIP/cal.c create mode 100755 reference/C/CONTRIB/SNIP/calsupp.c create mode 100755 reference/C/CONTRIB/SNIP/cant.c create mode 100755 reference/C/CONTRIB/SNIP/cast.h create mode 100755 reference/C/CONTRIB/SNIP/cbtrap.asm create mode 100755 reference/C/CONTRIB/SNIP/ccomcall.c create mode 100755 reference/C/CONTRIB/SNIP/cctrap.asm create mode 100755 reference/C/CONTRIB/SNIP/cdir.c create mode 100755 reference/C/CONTRIB/SNIP/center.c create mode 100755 reference/C/CONTRIB/SNIP/cerrinst.asm create mode 100755 reference/C/CONTRIB/SNIP/cerrtrap.asm create mode 100755 reference/C/CONTRIB/SNIP/changprn.c create mode 100755 reference/C/CONTRIB/SNIP/chbytes.c create mode 100755 reference/C/CONTRIB/SNIP/checkexe.c create mode 100755 reference/C/CONTRIB/SNIP/checksum.c create mode 100755 reference/C/CONTRIB/SNIP/chgext.c create mode 100755 reference/C/CONTRIB/SNIP/chmod.c create mode 100755 reference/C/CONTRIB/SNIP/clock.c create mode 100755 reference/C/CONTRIB/SNIP/cmdline.c create mode 100755 reference/C/CONTRIB/SNIP/coldboot.asm create mode 100755 reference/C/CONTRIB/SNIP/combin.c create mode 100755 reference/C/CONTRIB/SNIP/commafmt.c create mode 100755 reference/C/CONTRIB/SNIP/commconv.c create mode 100755 reference/C/CONTRIB/SNIP/compiler.c create mode 100755 reference/C/CONTRIB/SNIP/cpucheck.asm create mode 100755 reference/C/CONTRIB/SNIP/crc-16.c create mode 100755 reference/C/CONTRIB/SNIP/crc-16f.c create mode 100755 reference/C/CONTRIB/SNIP/crc_32.c create mode 100755 reference/C/CONTRIB/SNIP/crypt.c create mode 100755 reference/C/CONTRIB/SNIP/ctrlprnt.c create mode 100755 reference/C/CONTRIB/SNIP/cubic.c create mode 100755 reference/C/CONTRIB/SNIP/cursize.c create mode 100755 reference/C/CONTRIB/SNIP/cursor.c create mode 100755 reference/C/CONTRIB/SNIP/daynum.c create mode 100755 reference/C/CONTRIB/SNIP/dbl2long.c create mode 100755 reference/C/CONTRIB/SNIP/dblround.c create mode 100755 reference/C/CONTRIB/SNIP/dd_struc.h create mode 100755 reference/C/CONTRIB/SNIP/dirent.h create mode 100755 reference/C/CONTRIB/SNIP/dirmask.c create mode 100755 reference/C/CONTRIB/SNIP/do.c create mode 100755 reference/C/CONTRIB/SNIP/doansi.h create mode 100755 reference/C/CONTRIB/SNIP/doansi_1.c create mode 100755 reference/C/CONTRIB/SNIP/doansi_2.c create mode 100755 reference/C/CONTRIB/SNIP/dos5boot.h create mode 100755 reference/C/CONTRIB/SNIP/doscopy.c create mode 100755 reference/C/CONTRIB/SNIP/dosfuncs.txt create mode 100755 reference/C/CONTRIB/SNIP/dossort.c create mode 100755 reference/C/CONTRIB/SNIP/drivsrch.c create mode 100755 reference/C/CONTRIB/SNIP/droptime.c create mode 100755 reference/C/CONTRIB/SNIP/drvalid.c create mode 100755 reference/C/CONTRIB/SNIP/drvs.c create mode 100755 reference/C/CONTRIB/SNIP/dspclock.c create mode 100755 reference/C/CONTRIB/SNIP/dspdtst.c create mode 100755 reference/C/CONTRIB/SNIP/editgets.c create mode 100755 reference/C/CONTRIB/SNIP/eng.c create mode 100755 reference/C/CONTRIB/SNIP/enums.txt create mode 100755 reference/C/CONTRIB/SNIP/environ.txt create mode 100755 reference/C/CONTRIB/SNIP/errfix.c create mode 100755 reference/C/CONTRIB/SNIP/eval.c create mode 100755 reference/C/CONTRIB/SNIP/evsavres.txt create mode 100755 reference/C/CONTRIB/SNIP/except.doc create mode 100755 reference/C/CONTRIB/SNIP/ext_keys.c create mode 100755 reference/C/CONTRIB/SNIP/ext_keys.h create mode 100755 reference/C/CONTRIB/SNIP/factor.c create mode 100755 reference/C/CONTRIB/SNIP/factoryl.c create mode 100755 reference/C/CONTRIB/SNIP/faskbhit.c create mode 100755 reference/C/CONTRIB/SNIP/favail.c create mode 100755 reference/C/CONTRIB/SNIP/fcompare.c create mode 100755 reference/C/CONTRIB/SNIP/fcopy.c create mode 100755 reference/C/CONTRIB/SNIP/ferrorf.c create mode 100755 reference/C/CONTRIB/SNIP/filcount.c create mode 100755 reference/C/CONTRIB/SNIP/file_id.diz create mode 100755 reference/C/CONTRIB/SNIP/files.c create mode 100755 reference/C/CONTRIB/SNIP/fln_fix.c create mode 100755 reference/C/CONTRIB/SNIP/flnorm.c create mode 100755 reference/C/CONTRIB/SNIP/flopcopy.c create mode 100755 reference/C/CONTRIB/SNIP/fmemops.c create mode 100755 reference/C/CONTRIB/SNIP/fmtmoney.c create mode 100755 reference/C/CONTRIB/SNIP/fndislot.c create mode 100755 reference/C/CONTRIB/SNIP/format.c create mode 100755 reference/C/CONTRIB/SNIP/fpswitch.c create mode 100755 reference/C/CONTRIB/SNIP/fraction.c create mode 100755 reference/C/CONTRIB/SNIP/fscanbin.c create mode 100755 reference/C/CONTRIB/SNIP/fsize.c create mode 100755 reference/C/CONTRIB/SNIP/fsm.c create mode 100755 reference/C/CONTRIB/SNIP/ftime.c create mode 100755 reference/C/CONTRIB/SNIP/ftime.h create mode 100755 reference/C/CONTRIB/SNIP/getcmt.c create mode 100755 reference/C/CONTRIB/SNIP/getdcwd.c create mode 100755 reference/C/CONTRIB/SNIP/getkey.c create mode 100755 reference/C/CONTRIB/SNIP/getopt3.c create mode 100755 reference/C/CONTRIB/SNIP/getopts.c create mode 100755 reference/C/CONTRIB/SNIP/getopts.h create mode 100755 reference/C/CONTRIB/SNIP/getseg.c create mode 100755 reference/C/CONTRIB/SNIP/getstrng.c create mode 100755 reference/C/CONTRIB/SNIP/getvol.c create mode 100755 reference/C/CONTRIB/SNIP/glbl_env.c create mode 100755 reference/C/CONTRIB/SNIP/grafline.c create mode 100755 reference/C/CONTRIB/SNIP/grep.c create mode 100755 reference/C/CONTRIB/SNIP/head.c create mode 100755 reference/C/CONTRIB/SNIP/hexdump.c create mode 100755 reference/C/CONTRIB/SNIP/hexorint.c create mode 100755 reference/C/CONTRIB/SNIP/hilobyte.h create mode 100755 reference/C/CONTRIB/SNIP/hires.asm create mode 100755 reference/C/CONTRIB/SNIP/howdy.c create mode 100755 reference/C/CONTRIB/SNIP/hstr_i.c create mode 100755 reference/C/CONTRIB/SNIP/hugeread.c create mode 100755 reference/C/CONTRIB/SNIP/hugesort.c create mode 100755 reference/C/CONTRIB/SNIP/ifactor.c create mode 100755 reference/C/CONTRIB/SNIP/inchcvrt.c create mode 100755 reference/C/CONTRIB/SNIP/initvars.c create mode 100755 reference/C/CONTRIB/SNIP/int2e.asm create mode 100755 reference/C/CONTRIB/SNIP/iostutor.txt create mode 100755 reference/C/CONTRIB/SNIP/iscons.c create mode 100755 reference/C/CONTRIB/SNIP/isfopen.c create mode 100755 reference/C/CONTRIB/SNIP/isisbn.c create mode 100755 reference/C/CONTRIB/SNIP/isnetdr.c create mode 100755 reference/C/CONTRIB/SNIP/ispow2.c create mode 100755 reference/C/CONTRIB/SNIP/isqrt.c create mode 100755 reference/C/CONTRIB/SNIP/isramdsk.c create mode 100755 reference/C/CONTRIB/SNIP/isshare.c create mode 100755 reference/C/CONTRIB/SNIP/isshift.c create mode 100755 reference/C/CONTRIB/SNIP/iswprot.c create mode 100755 reference/C/CONTRIB/SNIP/isxkbrd.c create mode 100755 reference/C/CONTRIB/SNIP/jdn.c create mode 100755 reference/C/CONTRIB/SNIP/jgrep.c create mode 100755 reference/C/CONTRIB/SNIP/joystick.c create mode 100755 reference/C/CONTRIB/SNIP/kb_data.c create mode 100755 reference/C/CONTRIB/SNIP/kbflip.c create mode 100755 reference/C/CONTRIB/SNIP/keylocks.c create mode 100755 reference/C/CONTRIB/SNIP/keywatch.c create mode 100755 reference/C/CONTRIB/SNIP/killff.c create mode 100755 reference/C/CONTRIB/SNIP/lbitops.c create mode 100755 reference/C/CONTRIB/SNIP/ldfloor.c create mode 100755 reference/C/CONTRIB/SNIP/ll_msort.c create mode 100755 reference/C/CONTRIB/SNIP/ll_qsort.c create mode 100755 reference/C/CONTRIB/SNIP/log.c create mode 100755 reference/C/CONTRIB/SNIP/lsary.c create mode 100755 reference/C/CONTRIB/SNIP/lsd.c create mode 100755 reference/C/CONTRIB/SNIP/ltoa.c create mode 100755 reference/C/CONTRIB/SNIP/ltostr.c create mode 100755 reference/C/CONTRIB/SNIP/lv1ws.c create mode 100755 reference/C/CONTRIB/SNIP/lzhuf.c create mode 100755 reference/C/CONTRIB/SNIP/mainmain.c create mode 100755 reference/C/CONTRIB/SNIP/make.ini create mode 100755 reference/C/CONTRIB/SNIP/match.c create mode 100755 reference/C/CONTRIB/SNIP/match.doc create mode 100755 reference/C/CONTRIB/SNIP/match.h create mode 100755 reference/C/CONTRIB/SNIP/maze_1.c create mode 100755 reference/C/CONTRIB/SNIP/maze_2.c create mode 100755 reference/C/CONTRIB/SNIP/maze_3.c create mode 100755 reference/C/CONTRIB/SNIP/mcb_env.c create mode 100755 reference/C/CONTRIB/SNIP/mdalloc.c create mode 100755 reference/C/CONTRIB/SNIP/mem.c create mode 100755 reference/C/CONTRIB/SNIP/mem.h create mode 100755 reference/C/CONTRIB/SNIP/mem.txt create mode 100755 reference/C/CONTRIB/SNIP/memavail.c create mode 100755 reference/C/CONTRIB/SNIP/memrev.c create mode 100755 reference/C/CONTRIB/SNIP/missing.txt create mode 100755 reference/C/CONTRIB/SNIP/mkdirs.c create mode 100755 reference/C/CONTRIB/SNIP/mktone.c create mode 100755 reference/C/CONTRIB/SNIP/moon_age.c create mode 100755 reference/C/CONTRIB/SNIP/morse.c create mode 100755 reference/C/CONTRIB/SNIP/mouse.c create mode 100755 reference/C/CONTRIB/SNIP/mouse.h create mode 100755 reference/C/CONTRIB/SNIP/msb2ieee.c create mode 100755 reference/C/CONTRIB/SNIP/msc_peek.c create mode 100755 reference/C/CONTRIB/SNIP/mterm.c create mode 100755 reference/C/CONTRIB/SNIP/mv.c create mode 100755 reference/C/CONTRIB/SNIP/myio.cpp create mode 100755 reference/C/CONTRIB/SNIP/myio.h create mode 100755 reference/C/CONTRIB/SNIP/myio.mak create mode 100755 reference/C/CONTRIB/SNIP/myiodemo.cpp create mode 100755 reference/C/CONTRIB/SNIP/myline.cpp create mode 100755 reference/C/CONTRIB/SNIP/myline.h create mode 100755 reference/C/CONTRIB/SNIP/mystream.cpp create mode 100755 reference/C/CONTRIB/SNIP/mystream.h create mode 100755 reference/C/CONTRIB/SNIP/ndpcheck.asm create mode 100755 reference/C/CONTRIB/SNIP/noctrlc.c create mode 100755 reference/C/CONTRIB/SNIP/nonmsdos.txt create mode 100755 reference/C/CONTRIB/SNIP/noreset.c create mode 100755 reference/C/CONTRIB/SNIP/ord_text.c create mode 100755 reference/C/CONTRIB/SNIP/os_id.c create mode 100755 reference/C/CONTRIB/SNIP/os_id.h create mode 100755 reference/C/CONTRIB/SNIP/palndrom.c create mode 100755 reference/C/CONTRIB/SNIP/patmat.c create mode 100755 reference/C/CONTRIB/SNIP/pbmsrch.c create mode 100755 reference/C/CONTRIB/SNIP/pcnvrt.c create mode 100755 reference/C/CONTRIB/SNIP/pdn.lst create mode 100755 reference/C/CONTRIB/SNIP/perm_idx.c create mode 100755 reference/C/CONTRIB/SNIP/permute1.c create mode 100755 reference/C/CONTRIB/SNIP/permute2.c create mode 100755 reference/C/CONTRIB/SNIP/pfopen.c create mode 100755 reference/C/CONTRIB/SNIP/pi.c create mode 100755 reference/C/CONTRIB/SNIP/pi.h create mode 100755 reference/C/CONTRIB/SNIP/playdemo.c create mode 100755 reference/C/CONTRIB/SNIP/playlib.c create mode 100755 reference/C/CONTRIB/SNIP/pluraltx.c create mode 100755 reference/C/CONTRIB/SNIP/pmerge.c create mode 100755 reference/C/CONTRIB/SNIP/portable.h create mode 100755 reference/C/CONTRIB/SNIP/posix_ls.c create mode 100755 reference/C/CONTRIB/SNIP/posixdir.c create mode 100755 reference/C/CONTRIB/SNIP/pr.c create mode 100755 reference/C/CONTRIB/SNIP/printq.c create mode 100755 reference/C/CONTRIB/SNIP/prnspool.c create mode 100755 reference/C/CONTRIB/SNIP/prnspool.h create mode 100755 reference/C/CONTRIB/SNIP/prtoggle.c create mode 100755 reference/C/CONTRIB/SNIP/prtscrn.c create mode 100755 reference/C/CONTRIB/SNIP/prtstat.c create mode 100755 reference/C/CONTRIB/SNIP/psplit.c create mode 100755 reference/C/CONTRIB/SNIP/ptr_help.txt create mode 100755 reference/C/CONTRIB/SNIP/pushdir.c create mode 100755 reference/C/CONTRIB/SNIP/query.c create mode 100755 reference/C/CONTRIB/SNIP/rand1.c create mode 100755 reference/C/CONTRIB/SNIP/rand2.c create mode 100755 reference/C/CONTRIB/SNIP/rdxcnvrt.c create mode 100755 reference/C/CONTRIB/SNIP/read.me create mode 100755 reference/C/CONTRIB/SNIP/reboot.c create mode 100755 reference/C/CONTRIB/SNIP/redir.c create mode 100755 reference/C/CONTRIB/SNIP/remtab.c create mode 100755 reference/C/CONTRIB/SNIP/resource.lst create mode 100755 reference/C/CONTRIB/SNIP/rfind1st.c create mode 100755 reference/C/CONTRIB/SNIP/rg_isort.c create mode 100755 reference/C/CONTRIB/SNIP/rg_qsort.c1 create mode 100755 reference/C/CONTRIB/SNIP/rg_qsort.c2 create mode 100755 reference/C/CONTRIB/SNIP/rg_rand.c create mode 100755 reference/C/CONTRIB/SNIP/rg_ssort.c create mode 100755 reference/C/CONTRIB/SNIP/rm_all.c create mode 100755 reference/C/CONTRIB/SNIP/rmallws.c create mode 100755 reference/C/CONTRIB/SNIP/rmlead.c create mode 100755 reference/C/CONTRIB/SNIP/rmtrail.c create mode 100755 reference/C/CONTRIB/SNIP/rndmize.c create mode 100755 reference/C/CONTRIB/SNIP/roman.c create mode 100755 reference/C/CONTRIB/SNIP/round.h create mode 100755 reference/C/CONTRIB/SNIP/rtlftrul.txt create mode 100755 reference/C/CONTRIB/SNIP/scaldate.c create mode 100755 reference/C/CONTRIB/SNIP/scaldate.h create mode 100755 reference/C/CONTRIB/SNIP/scanfrac.c create mode 100755 reference/C/CONTRIB/SNIP/scrnmacs.h create mode 100755 reference/C/CONTRIB/SNIP/scrnpick.c create mode 100755 reference/C/CONTRIB/SNIP/scrnsave.c create mode 100755 reference/C/CONTRIB/SNIP/scroll.c create mode 100755 reference/C/CONTRIB/SNIP/setenvar.c create mode 100755 reference/C/CONTRIB/SNIP/setimeto.c create mode 100755 reference/C/CONTRIB/SNIP/setvol.c create mode 100755 reference/C/CONTRIB/SNIP/sharing.txt create mode 100755 reference/C/CONTRIB/SNIP/shel2dos.c create mode 100755 reference/C/CONTRIB/SNIP/snippets._c_ create mode 100755 reference/C/CONTRIB/SNIP/snippets.ndx create mode 100755 reference/C/CONTRIB/SNIP/snippets.txt create mode 100755 reference/C/CONTRIB/SNIP/snippets.wc create mode 100755 reference/C/CONTRIB/SNIP/sound.c create mode 100755 reference/C/CONTRIB/SNIP/sound.h create mode 100755 reference/C/CONTRIB/SNIP/soundex.c create mode 100755 reference/C/CONTRIB/SNIP/speed.c create mode 100755 reference/C/CONTRIB/SNIP/spin.c create mode 100755 reference/C/CONTRIB/SNIP/split.c create mode 100755 reference/C/CONTRIB/SNIP/srchfile.c create mode 100755 reference/C/CONTRIB/SNIP/sstrcpy.c create mode 100755 reference/C/CONTRIB/SNIP/stats.c create mode 100755 reference/C/CONTRIB/SNIP/storage.typ create mode 100755 reference/C/CONTRIB/SNIP/stptok.c create mode 100755 reference/C/CONTRIB/SNIP/str.cpp create mode 100755 reference/C/CONTRIB/SNIP/str.doc create mode 100755 reference/C/CONTRIB/SNIP/str.h create mode 100755 reference/C/CONTRIB/SNIP/str27seg.c create mode 100755 reference/C/CONTRIB/SNIP/strat.c create mode 100755 reference/C/CONTRIB/SNIP/strat.h create mode 100755 reference/C/CONTRIB/SNIP/strdup.c create mode 100755 reference/C/CONTRIB/SNIP/strecpy.asm create mode 100755 reference/C/CONTRIB/SNIP/strftime.c create mode 100755 reference/C/CONTRIB/SNIP/stripeof.c create mode 100755 reference/C/CONTRIB/SNIP/strrepl.c create mode 100755 reference/C/CONTRIB/SNIP/strrev.c create mode 100755 reference/C/CONTRIB/SNIP/strsort.c create mode 100755 reference/C/CONTRIB/SNIP/strucfil.c create mode 100755 reference/C/CONTRIB/SNIP/strupr.c create mode 100755 reference/C/CONTRIB/SNIP/stub.c create mode 100755 reference/C/CONTRIB/SNIP/style.c create mode 100755 reference/C/CONTRIB/SNIP/sunriset.c create mode 100755 reference/C/CONTRIB/SNIP/tabtrick.c create mode 100755 reference/C/CONTRIB/SNIP/tail.c create mode 100755 reference/C/CONTRIB/SNIP/tasker.c create mode 100755 reference/C/CONTRIB/SNIP/tasker.h create mode 100755 reference/C/CONTRIB/SNIP/tasker.txt create mode 100755 reference/C/CONTRIB/SNIP/testcmt.c create mode 100755 reference/C/CONTRIB/SNIP/timegetc.c create mode 100755 reference/C/CONTRIB/SNIP/toascii.c create mode 100755 reference/C/CONTRIB/SNIP/todaybak.c create mode 100755 reference/C/CONTRIB/SNIP/toolkit.h create mode 100755 reference/C/CONTRIB/SNIP/touch.c create mode 100755 reference/C/CONTRIB/SNIP/tp6tod.c create mode 100755 reference/C/CONTRIB/SNIP/translat.c create mode 100755 reference/C/CONTRIB/SNIP/trapdemo.c create mode 100755 reference/C/CONTRIB/SNIP/trapflag.asm create mode 100755 reference/C/CONTRIB/SNIP/treedir.c create mode 100755 reference/C/CONTRIB/SNIP/trim.c create mode 100755 reference/C/CONTRIB/SNIP/truename.c create mode 100755 reference/C/CONTRIB/SNIP/uclock.c create mode 100755 reference/C/CONTRIB/SNIP/uclock.h create mode 100755 reference/C/CONTRIB/SNIP/unix2dos.c create mode 100755 reference/C/CONTRIB/SNIP/uudecode.c create mode 100755 reference/C/CONTRIB/SNIP/uuencode.c create mode 100755 reference/C/CONTRIB/SNIP/vfname.c create mode 100755 reference/C/CONTRIB/SNIP/video.c create mode 100755 reference/C/CONTRIB/SNIP/vidport.c create mode 100755 reference/C/CONTRIB/SNIP/vio.asm create mode 100755 reference/C/CONTRIB/SNIP/vio.h create mode 100755 reference/C/CONTRIB/SNIP/vt100.txt create mode 100755 reference/C/CONTRIB/SNIP/w_wrap.c create mode 100755 reference/C/CONTRIB/SNIP/w_wrap.h create mode 100755 reference/C/CONTRIB/SNIP/wb_fcopy.c create mode 100755 reference/C/CONTRIB/SNIP/wc.c create mode 100755 reference/C/CONTRIB/SNIP/weird.c create mode 100755 reference/C/CONTRIB/SNIP/where.c create mode 100755 reference/C/CONTRIB/SNIP/which_c.txt create mode 100755 reference/C/CONTRIB/SNIP/whicharc.c create mode 100755 reference/C/CONTRIB/SNIP/windchil.c create mode 100755 reference/C/CONTRIB/SNIP/wordwrap.c create mode 100755 reference/C/CONTRIB/SNIP/x00api.c create mode 100755 reference/C/CONTRIB/SNIP/x00api.h create mode 100755 reference/C/CONTRIB/SNIP/xfile.c create mode 100755 reference/C/CONTRIB/SNIP/xfile.h create mode 100755 reference/C/CONTRIB/SNIP/xstrcat.c create mode 100755 reference/C/CONTRIB/SNIP/xstrcmp.c create mode 100755 reference/C/CONTRIB/SNIP/xtest.c create mode 100644 reference/C/CONTRIB/YABL/Makefile.am create mode 100644 reference/C/CONTRIB/YABL/Makefile.in create mode 100644 reference/C/CONTRIB/YABL/yabl create mode 100755 reference/C/CONTRIB/intro.html (limited to 'reference/C/CONTRIB') diff --git a/reference/C/CONTRIB/Makefile.am b/reference/C/CONTRIB/Makefile.am new file mode 100644 index 0000000..603c471 --- /dev/null +++ b/reference/C/CONTRIB/Makefile.am @@ -0,0 +1,6 @@ +EXTRA_DIST = $(wildcard *.html) $(wildcard *.gif) +SUBDIRS = OR_PRACTICAL_C OR_USING_C SAWTELL SNIP YABL +docs_DATA = $(EXTRA_DIST) + +docsdir = $(kde_htmldir)/en/kdevelop/$(subdir) + diff --git a/reference/C/CONTRIB/Makefile.in b/reference/C/CONTRIB/Makefile.in new file mode 100644 index 0000000..49a11c7 --- /dev/null +++ b/reference/C/CONTRIB/Makefile.in @@ -0,0 +1,528 @@ +# KDE tags expanded automatically by am_edit - $Revision: 1.2 $ +# Makefile.in generated automatically by automake 1.5 from Makefile.am. + +# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +# Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = ../../.. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_HEADER = $(INSTALL_DATA) +transform = @program_transform_name@ +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_alias = @build_alias@ +build_triplet = @build@ +host_alias = @host_alias@ +host_triplet = @host@ +target_alias = @target_alias@ +target_triplet = @target@ +AMTAR = @AMTAR@ +ARTSCCONFIG = @ARTSCCONFIG@ +AS = @AS@ +AUTODIRS = @AUTODIRS@ +AWK = @AWK@ +CC = @CC@ +CONF_FILES = @CONF_FILES@ +CPP = @CPP@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +DCOPIDL = @DCOPIDL@ +DCOPIDL2CPP = @DCOPIDL2CPP@ +DCOP_DEPENDENCIES = @DCOP_DEPENDENCIES@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DPMSINC = @DPMSINC@ +DPMSLIB = @DPMSLIB@ +EXEEXT = @EXEEXT@ +GCJ = @GCJ@ +GCJFLAGS = @GCJFLAGS@ +GLINC = @GLINC@ +GLLIB = @GLLIB@ +GMSGFMT = @GMSGFMT@ +IDL = @IDL@ +IDL_DEPENDENCIES = @IDL_DEPENDENCIES@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +JAR = @JAR@ +JAVAC = @JAVAC@ +JAVAH = @JAVAH@ +JVMLIBS = @JVMLIBS@ +KDECONFIG = @KDECONFIG@ +KDE_CXXFLAGS = @KDE_CXXFLAGS@ +KDE_EXTRA_RPATH = @KDE_EXTRA_RPATH@ +KDE_INCLUDES = @KDE_INCLUDES@ +KDE_LDFLAGS = @KDE_LDFLAGS@ +KDE_PLUGIN = @KDE_PLUGIN@ +KDE_RPATH = @KDE_RPATH@ +KDE_USE_CLOSURE_FALSE = @KDE_USE_CLOSURE_FALSE@ +KDE_USE_CLOSURE_TRUE = @KDE_USE_CLOSURE_TRUE@ +KDE_USE_FINAL_FALSE = @KDE_USE_FINAL_FALSE@ +KDE_USE_FINAL_TRUE = @KDE_USE_FINAL_TRUE@ +KDE_XSL_STYLESHEET = @KDE_XSL_STYLESHEET@ +LIBCOMPAT = @LIBCOMPAT@ +LIBCRYPT = @LIBCRYPT@ +LIBDL = @LIBDL@ +LIBGEN = @LIBGEN@ +LIBJPEG = @LIBJPEG@ +LIBMICO = @LIBMICO@ +LIBOBJS = @LIBOBJS@ +LIBPNG = @LIBPNG@ +LIBPTHREAD = @LIBPTHREAD@ +LIBPYTHON = @LIBPYTHON@ +LIBQIMGIO = @LIBQIMGIO@ +LIBRESOLV = @LIBRESOLV@ +LIBSHADOW = @LIBSHADOW@ +LIBSM = @LIBSM@ +LIBSOCKET = @LIBSOCKET@ +LIBTIFF = @LIBTIFF@ +LIBTOOL = @LIBTOOL@ +LIBUCB = @LIBUCB@ +LIBUTIL = @LIBUTIL@ +LIBXINERAMA = @LIBXINERAMA@ +LIBZ = @LIBZ@ +LIB_KAB = @LIB_KAB@ +LIB_KDECORE = @LIB_KDECORE@ +LIB_KDEUI = @LIB_KDEUI@ +LIB_KFILE = @LIB_KFILE@ +LIB_KFM = @LIB_KFM@ +LIB_KFORMULA = @LIB_KFORMULA@ +LIB_KHTML = @LIB_KHTML@ +LIB_KIMGIO = @LIB_KIMGIO@ +LIB_KIO = @LIB_KIO@ +LIB_KPARTS = @LIB_KPARTS@ +LIB_KSPELL = @LIB_KSPELL@ +LIB_KSYCOCA = @LIB_KSYCOCA@ +LIB_KWRITE = @LIB_KWRITE@ +LIB_QT = @LIB_QT@ +LIB_SMB = @LIB_SMB@ +LIB_X11 = @LIB_X11@ +LN_S = @LN_S@ +MCOPIDL = @MCOPIDL@ +MEINPROC = @MEINPROC@ +MICO_INCLUDES = @MICO_INCLUDES@ +MICO_LDFLAGS = @MICO_LDFLAGS@ +MOC = @MOC@ +MSGFMT = @MSGFMT@ +NOOPT_CXXFLAGS = @NOOPT_CXXFLAGS@ +NOREPO = @NOREPO@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PAMLIBS = @PAMLIBS@ +PASSWDLIBS = @PASSWDLIBS@ +PYTHONINC = @PYTHONINC@ +PYTHONLIB = @PYTHONLIB@ +PYTHONMODDIR = @PYTHONMODDIR@ +QT_INCLUDES = @QT_INCLUDES@ +QT_LDFLAGS = @QT_LDFLAGS@ +RANLIB = @RANLIB@ +REPO = @REPO@ +SETUIDFLAGS = @SETUIDFLAGS@ +STRIP = @STRIP@ +TOPSUBDIRS = @TOPSUBDIRS@ +UIC = @UIC@ +UIC_TR = @UIC_TR@ +USER_INCLUDES = @USER_INCLUDES@ +USER_LDFLAGS = @USER_LDFLAGS@ +USE_EXCEPTIONS = @USE_EXCEPTIONS@ +USE_RTTI = @USE_RTTI@ +USE_THREADS = @USE_THREADS@ +VERSION = @VERSION@ +XGETTEXT = @XGETTEXT@ +XPMINC = @XPMINC@ +XPMLIB = @XPMLIB@ +X_EXTRA_LIBS = @X_EXTRA_LIBS@ +X_INCLUDES = @X_INCLUDES@ +X_LDFLAGS = @X_LDFLAGS@ +X_PRE_LIBS = @X_PRE_LIBS@ +all_includes = @all_includes@ +all_libraries = @all_libraries@ +am__include = @am__include@ +am__quote = @am__quote@ +idldir = @idldir@ +install_sh = @install_sh@ +jni_includes = @jni_includes@ +kde_appsdir = @kde_appsdir@ +kde_bindir = @kde_bindir@ +kde_confdir = @kde_confdir@ +kde_datadir = @kde_datadir@ +kde_htmldir = @kde_htmldir@ +kde_icondir = @kde_icondir@ +kde_includes = @kde_includes@ +kde_libraries = @kde_libraries@ +kde_libs_htmldir = @kde_libs_htmldir@ +kde_libs_prefix = @kde_libs_prefix@ +kde_locale = @kde_locale@ +kde_mimedir = @kde_mimedir@ +kde_moduledir = @kde_moduledir@ +kde_qtver = @kde_qtver@ +kde_servicesdir = @kde_servicesdir@ +kde_servicetypesdir = @kde_servicetypesdir@ +kde_sounddir = @kde_sounddir@ +kde_templatesdir = @kde_templatesdir@ +kde_wallpaperdir = @kde_wallpaperdir@ +micodir = @micodir@ +qt_includes = @qt_includes@ +qt_libraries = @qt_libraries@ +x_includes = @x_includes@ +x_libraries = @x_libraries@ + +EXTRA_DIST = $(wildcard *.html) $(wildcard *.gif) +SUBDIRS = OR_PRACTICAL_C OR_USING_C SAWTELL SNIP YABL +docs_DATA = $(EXTRA_DIST) + +docsdir = $(kde_htmldir)/en/kdevelop/$(subdir) +subdir = reference/C/CONTRIB +mkinstalldirs = $(SHELL) $(top_srcdir)/admin/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +DIST_SOURCES = +DATA = $(docs_DATA) + + +RECURSIVE_TARGETS = info-recursive dvi-recursive install-info-recursive \ + uninstall-info-recursive all-recursive install-data-recursive \ + install-exec-recursive installdirs-recursive install-recursive \ + uninstall-recursive check-recursive installcheck-recursive +DIST_COMMON = Makefile.am Makefile.in +DIST_SUBDIRS = $(SUBDIRS) +#>- all: all-recursive +#>+ 1 +all: docs-am all-recursive + +.SUFFIXES: + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) +#>- cd $(top_srcdir) && \ +#>- $(AUTOMAKE) --gnu reference/C/CONTRIB/Makefile +#>+ 3 + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu reference/C/CONTRIB/Makefile + cd $(top_srcdir) && perl admin/am_edit reference/C/CONTRIB/Makefile.in +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) && \ + CONFIG_HEADERS= CONFIG_LINKS= \ + CONFIG_FILES=$(subdir)/$@ $(SHELL) ./config.status +uninstall-info-am: +install-docsDATA: $(docs_DATA) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(docsdir) + @list='$(docs_DATA)'; for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + f="`echo $$p | sed -e 's|^.*/||'`"; \ + echo " $(INSTALL_DATA) $$d$$p $(DESTDIR)$(docsdir)/$$f"; \ + $(INSTALL_DATA) $$d$$p $(DESTDIR)$(docsdir)/$$f; \ + done + +uninstall-docsDATA: + @$(NORMAL_UNINSTALL) + @list='$(docs_DATA)'; for p in $$list; do \ + f="`echo $$p | sed -e 's|^.*/||'`"; \ + echo " rm -f $(DESTDIR)$(docsdir)/$$f"; \ + rm -f $(DESTDIR)$(docsdir)/$$f; \ + done + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. +$(RECURSIVE_TARGETS): + @set fnord $(MAKEFLAGS); amf=$$2; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +mostlyclean-recursive clean-recursive distclean-recursive \ + maintainer-clean-recursive: + @set fnord $(MAKEFLAGS); amf=$$2; \ + dot_seen=no; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + rev=''; for subdir in $$list; do \ + if test "$$subdir" = "."; then :; else \ + rev="$$subdir $$rev"; \ + fi; \ + done; \ + rev="$$rev ."; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique $(LISP) + +TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ + || etags $(ETAGS_ARGS) $$tags $$unique $(LISP) + +GTAGS: + here=`CDPATH=: && cd $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH + +#>- DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +#>+ 4 +KDE_DIST=intro.html + +DISTFILES= $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) $(KDE_DIST) + + +top_distdir = ../../.. +distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + if test -f $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + $(mkinstalldirs) "$(distdir)/$$dir"; \ + fi; \ + if test -d $$d/$$file; then \ + cp -pR $$d/$$file $(distdir) \ + || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done + for subdir in $(SUBDIRS); do \ + if test "$$subdir" = .; then :; else \ + test -d $(distdir)/$$subdir \ + || mkdir $(distdir)/$$subdir \ + || exit 1; \ + (cd $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$(top_distdir)" \ + distdir=../$(distdir)/$$subdir \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-recursive +all-am: Makefile $(DATA) +installdirs: installdirs-recursive +installdirs-am: + $(mkinstalldirs) $(DESTDIR)$(docsdir) + +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) stamp-h stamp-h[0-9]* + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +#>- clean: clean-recursive +#>+ 1 +clean: kde-rpo-clean clean-recursive + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-recursive + +distclean-am: clean-am distclean-generic distclean-libtool \ + distclean-tags + +dvi: dvi-recursive + +dvi-am: + +info: info-recursive + +info-am: + +install-data-am: install-docsDATA + +install-exec-am: + +install-info: install-info-recursive + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +uninstall-am: uninstall-docsDATA uninstall-info-am + +uninstall-info: uninstall-info-recursive + +.PHONY: $(RECURSIVE_TARGETS) GTAGS all all-am check check-am clean \ + clean-generic clean-libtool clean-recursive distclean \ + distclean-generic distclean-libtool distclean-recursive \ + distclean-tags distdir dvi dvi-am dvi-recursive info info-am \ + info-recursive install install-am install-data install-data-am \ + install-data-recursive install-docsDATA install-exec \ + install-exec-am install-exec-recursive install-info \ + install-info-am install-info-recursive install-man \ + install-recursive install-strip installcheck installcheck-am \ + installdirs installdirs-am installdirs-recursive \ + maintainer-clean maintainer-clean-generic \ + maintainer-clean-recursive mostlyclean mostlyclean-generic \ + mostlyclean-libtool mostlyclean-recursive tags tags-recursive \ + uninstall uninstall-am uninstall-docsDATA uninstall-info-am \ + uninstall-info-recursive uninstall-recursive + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: + +#>+ 2 +docs-am: + +#>+ 6 +force-reedit: + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu reference/C/CONTRIB/Makefile + cd $(top_srcdir) && perl admin/am_edit reference/C/CONTRIB/Makefile.in + + +#>+ 2 +final: + $(MAKE) all-am +#>+ 2 +final-install: + $(MAKE) install-am +#>+ 2 +no-final: + $(MAKE) all-am +#>+ 2 +no-final-install: + $(MAKE) install-am +#>+ 3 +cvs-clean: + $(MAKE) -f $(top_srcdir)/admin/Makefile.common cvs-clean + +#>+ 3 +kde-rpo-clean: + -rm -f *.rpo diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/01_1.c b/reference/C/CONTRIB/OR_PRACTICAL_C/01_1.c new file mode 100644 index 0000000..7c852bf --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/01_1.c @@ -0,0 +1,6 @@ +#include +main() +{ + (void) printf("Hello World\n"); + return (0); +} diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/01_2.c b/reference/C/CONTRIB/OR_PRACTICAL_C/01_2.c new file mode 100644 index 0000000..7c852bf --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/01_2.c @@ -0,0 +1,6 @@ +#include +main() +{ + (void) printf("Hello World\n"); + return (0); +} diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/02_1.c b/reference/C/CONTRIB/OR_PRACTICAL_C/02_1.c new file mode 100644 index 0000000..63ebe38 --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/02_1.c @@ -0,0 +1,18 @@ +/******************************************************** + * hello -- program to print out "Hello World". * + * Not an especially earth-shattering program. * + * * + * Author: Steve Oualline * + * * + * Purpose: Demonstration of a simple program * + * * + * Usage: * + * Run the program and the message appears * + ********************************************************/ +#include +main() +{ + /* Tell the world hello */ + (void) printf("Hello World\n"); + return (0); +} diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/03_1.c b/reference/C/CONTRIB/OR_PRACTICAL_C/03_1.c new file mode 100644 index 0000000..db625d5 --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/03_1.c @@ -0,0 +1,5 @@ +main() +{ + (1 + 2) * 4; + return (0); +} diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/03_2.c b/reference/C/CONTRIB/OR_PRACTICAL_C/03_2.c new file mode 100644 index 0000000..915998b --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/03_2.c @@ -0,0 +1,13 @@ +#include + +int term; /* term used in two expressions */ +int term_2; /* twice term */ +int term_3; /* three times term */ +main() +{ + + term = 3 * 5; + term_2 = 2 * term; + term_3 = 3 * term; + return (0); +} diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/03_3.c b/reference/C/CONTRIB/OR_PRACTICAL_C/03_3.c new file mode 100644 index 0000000..e97347e --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/03_3.c @@ -0,0 +1,11 @@ +#include + +int term; /* term used in two expressions */ +main() +{ + + term = 3 * 5; + (void)printf("Twice %d is %d\n", term, 2*term); + (void)printf("Three time %d is %d\n", term, 3*term); + return (0); +} diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/03_4.c b/reference/C/CONTRIB/OR_PRACTICAL_C/03_4.c new file mode 100644 index 0000000..ac008b9 --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/03_4.c @@ -0,0 +1,16 @@ +#include + +char char1; /* first character */ +char char2; /* second character */ +char char3; /* third character */ + +main() +{ + char1 = 'A'; + char2 = 'B'; + char3 = 'C'; + (void)printf("%c%c%c reversed is %c%c%c\n", + char1, char2, char3, + char3, char2, char1); + return (0); +} diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/04_1.c b/reference/C/CONTRIB/OR_PRACTICAL_C/04_1.c new file mode 100644 index 0000000..caa3401 --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/04_1.c @@ -0,0 +1,19 @@ +#include + +float data[5]; /* data to average and total */ +float total; /* the total of the data items */ +float average; /* average of the items */ + +main() +{ + data[0] = 34.0; + data[1] = 27.0; + data[2] = 45.0; + data[3] = 82.0; + data[4] = 22.0; + + total = data[0] + data[1] + data[2] + data[3] + data[4]; + average = total / 5.0; + (void)printf("Total %f Average %f\n", total, average); + return (0); +} diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/04_2.c b/reference/C/CONTRIB/OR_PRACTICAL_C/04_2.c new file mode 100644 index 0000000..5fa81b3 --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/04_2.c @@ -0,0 +1,9 @@ +#include +#include +char name[30]; /* First name of someone */ +main() +{ + (void)strcpy(name, "Sam"); /* Initialize the name */ + (void)printf("The name is %s\n", name); + return (0); +} diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/04_3.c b/reference/C/CONTRIB/OR_PRACTICAL_C/04_3.c new file mode 100644 index 0000000..14ee846 --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/04_3.c @@ -0,0 +1,20 @@ +#include +#include + +char first[100]; /* first name */ +char last[100]; /* last name */ +char full_name[200]; /* full version of first and last name */ + +main() +{ + (void)strcpy(first, "Steve"); /* Initialize first name */ + (void)strcpy(last, "Oualline"); /* Initialize last name */ + + (void)strcpy(full_name, first); /* full = "Steve" */ + /* Note: strcat not strcpy */ + (void)strcat(full_name, " "); /* full = "Steve " */ + (void)strcat(full_name, last); /* full = "Steve Oualline" */ + + (void)printf("The full name is %s\n", full_name); + return (0); +} diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/04_4.c b/reference/C/CONTRIB/OR_PRACTICAL_C/04_4.c new file mode 100644 index 0000000..2fa8ced --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/04_4.c @@ -0,0 +1,13 @@ +#include +#include + +char line[100]; + +main() +{ + (void)printf("Enter a line: "); + (void)fgets(line, sizeof(line), stdin); + + (void)printf("The length of the line is: %d\n", strlen(line)); + return (0); +} diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/04_5.c b/reference/C/CONTRIB/OR_PRACTICAL_C/04_5.c new file mode 100644 index 0000000..a651145 --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/04_5.c @@ -0,0 +1,22 @@ +#include +#include + +char first[100]; /* first name of person we are working with */ +char last[100]; /* His last name */ + +/* First and last name of the person (computed) */ +char full[200]; +main() { + (void)printf("Enter first name: "); + (void)fgets(first, sizeof(first), stdin); + + (void)printf("Enter last name: "); + (void)fgets(last, sizeof(last), stdin); + + (void)strcpy(full, first); + (void)strcat(full, " "); + (void)strcat(full, last); + + (void)printf("The name is %s\n", full); + return (0); +} diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/04_6.c b/reference/C/CONTRIB/OR_PRACTICAL_C/04_6.c new file mode 100644 index 0000000..a6b6e66 --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/04_6.c @@ -0,0 +1,26 @@ +#include +#include + +char first[100]; /* first name of person we are working with */ +char last[100]; /* His last name */ + +/* First and last name of the person (computed) */ +char full[100]; +main() { + (void)printf("Enter first name: "); + (void)fgets(first, sizeof(first), stdin); + /* trim off last character */ + first[strlen(first)-1] = '\0'; + + (void)printf("Enter last name: "); + (void)fgets(last, sizeof(last), stdin); + /* trim off last character */ + last[strlen(last)-1] = '\0'; + + (void)strcpy(full, first); + (void)strcat(full, " "); + (void)strcat(full, last); + + (void)printf("The name is %s\n", full); + return (0); +} diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/04_7.c b/reference/C/CONTRIB/OR_PRACTICAL_C/04_7.c new file mode 100644 index 0000000..9116633 --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/04_7.c @@ -0,0 +1,13 @@ +#include +char line[100]; /* input line from console */ +int value; /* a value to double */ + +main() +{ + (void) printf("Enter a value: "); + (void) fgets(line, sizeof(line), stdin); + (void) sscanf(line, "%d", &value); + (void) printf("Twice %d is %d\n", + value, value * 2); + return (0); +} diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/05_1.c b/reference/C/CONTRIB/OR_PRACTICAL_C/05_1.c new file mode 100644 index 0000000..6b5e8f2 --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/05_1.c @@ -0,0 +1,25 @@ +#include +int old_number; /* previous Fibonacci number */ + +int current_number; /* current Fibonacci number */ + +int next_number; /* next number in the series */ + +main() +{ + /* start things out */ + old_number = 1; + current_number = 1; + + (void)printf("1\n"); /* Print first number */ + + while (current_number < 100) { + + (void) printf("%d\n", current_number); + next_number = current_number + old_number; + + old_number = current_number; + current_number = next_number; + } + return (0); +} diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/05_2.c b/reference/C/CONTRIB/OR_PRACTICAL_C/05_2.c new file mode 100644 index 0000000..d1d41ea --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/05_2.c @@ -0,0 +1,25 @@ +#include +char line[100];/* line of data for input */ + +/* Running total of all numbers so far */ +int total; + +/* next item to add to the list */ +int item; + +main() +{ + total = 0; + while (1) { + (void) printf("Enter # to add \n"); + (void) printf(" or 0 to stop:"); + (void) fgets(line, sizeof(line), stdin); + (void) sscanf(line, "%d", &item); + if (item == 0) + break; + total += item; + (void) printf("Total: %d\n", total); + } + (void) printf("Final total %d\n", total); + return (0); +} diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/05_3.c b/reference/C/CONTRIB/OR_PRACTICAL_C/05_3.c new file mode 100644 index 0000000..c3c51e1 --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/05_3.c @@ -0,0 +1,38 @@ +#include +char line[100]; /* line from input */ + +/* Running total of all numbers so far */ +int total; + +/* next item to add to the list */ +int item; + +/* number of negative items */ +int minus_items; + +main() +{ + total = 0; + minus_items = 0; + while (1) { + (void) printf("Enter # to add\n"); + (void) printf(" or 0 to stop:"); + (void) fgets(line, sizeof(line), stdin); + (void) sscanf(line, "%d", &item); + + if (item == 0) + break; + + if (item < 0) { + minus_items++; + continue; + } + total += item; + (void) printf("Total: %d\n", total); + } + + (void) printf("Final total %d\n", total); + (void) printf("with %d negative items omitted\n", + minus_items); + return (0); +} diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/06_1.c b/reference/C/CONTRIB/OR_PRACTICAL_C/06_1.c new file mode 100644 index 0000000..8f889a5 --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/06_1.c @@ -0,0 +1,25 @@ +#include +char line[100];/* line of data from the input */ + +int result; /* the result of the calculations */ +char operator; /* operator the user specified */ +int value; /* value specified after the operator */ +main() +{ + result = 0; /* initialize the result */ + + /* Loop forever (or till we hit the break statement) */ + while (1) { + (void) printf("Result: %d\n", result); + + (void) printf("Enter operator and number: "); + (void) fgets(line, sizeof(line), stdin); + (void) sscanf(line, "%c %d", &operator, &value); + + if (operator = '+') { + result += value; + } else { + (void) printf("Unknown operator %c\n", operator); + } + } +} diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/06_2.c b/reference/C/CONTRIB/OR_PRACTICAL_C/06_2.c new file mode 100644 index 0000000..1bdfb0f --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/06_2.c @@ -0,0 +1,39 @@ +#include +char line[100];/* line of text from input */ + +int result; /* the result of the calculations */ +char operator; /* operator the user specified */ +int value; /* value specified after the operator */ +main() +{ + result = 0; /* initialize the result */ + + /* loop forever (or until break reached) */ + while (1) { + (void) printf("Result: %d\n", result); + (void) printf("Enter operator and number: "); + + (void) fgets(line, sizeof(line), stdin); + (void) sscanf(line, "%c %d", &operator, &value); + + if ((operator == 'q') || (operator == 'Q')) + break; + + if (operator == '+') { + result += value; + } else if (operator == '-') { + result -= value; + } else if (operator == '*') { + result *= value; + } else if (operator == '/') { + if (value == 0) { + (void)printf("Error:Divide by zero\n"); + (void)printf(" operation ignored\n"); + } else + result /= value; + } else { + (void) printf("Unknown operator %c\n", operator); + } + } + return (0); +} diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/06_3.c b/reference/C/CONTRIB/OR_PRACTICAL_C/06_3.c new file mode 100644 index 0000000..bc0598a --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/06_3.c @@ -0,0 +1,66 @@ +/******************************************************** + * guess -- a simple guessing game * + * * + * Usage: * + * guess * + * * + * A random number is chosen between 1 and 100. * + * The player is given a set of bounds and * + * must choose a number between them. * + * If the player chooses the correct number he wins* + * Otherwise the bounds are adjusted to reflect * + * the player's guess and the game continues. * + * * + * * + * Restrictions: * + * The random number is generated by the statement * + * rand() % 100. Because rand() returns a number * + * 0 <= rand() <= maxint this slightly favors * + * the lower numbers. * + ********************************************************/ +#include +#include /* ANSI Standard only */ +int number_to_guess; /* random number to be guessed */ +int low_limit; /* current lower limit of player's range */ +int high_limit; /* current upper limit of player's range */ +int guess_count; /* number of times player guessed */ +int player_number; /* number gotten from the player */ +char line[80]; /* input buffer for a single line */ +main() +{ + while (1) { + /* + * Not a pure random number, see restrictions + */ + number_to_guess = rand() % 100 + 1; + + /* Initialize variables for loop */ + low_limit = 0; + high_limit = 100; + guess_count = 0; + + while (1) { + /* tell user what the bounds are and get his guess */ + (void) printf("Bounds %d - %d\n", low_limit, high_limit); + (void) printf("Value[%d]? ", guess_count); + + guess_count++; + + (void) fgets(line, sizeof(line), stdin); + (void) sscanf(line, "%d", &player_number); + + /* did he guess right? */ + if (player_number == number_to_guess) + break; + + /* adjust bounds for next guess */ + if (player_number < number_to_guess) + low_limit = player_number; + else + high_limit = player_number; + + } + (void) printf("Bingo\n"); + } + return (0); +} diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/07_1.c b/reference/C/CONTRIB/OR_PRACTICAL_C/07_1.c new file mode 100644 index 0000000..ab87eb1 --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/07_1.c @@ -0,0 +1,24 @@ +#include + +int total; /* total of all the numbers */ +int current; /* current value from the user */ +int counter; /* while loop counter */ + +char line[80]; /* Line from keyboard */ + +main() { + total = 0; + + counter = 0; + while (counter < 5) { + (void)printf("Number? "); + + (void)fgets(line, sizeof(line), stdin); + (void)sscanf(line, "%d", ¤t); + total += current; + + counter++; + } + (void)printf("The grand total is %d\n", total); + return (0); +} diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/07_2.c b/reference/C/CONTRIB/OR_PRACTICAL_C/07_2.c new file mode 100644 index 0000000..02eedd6 --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/07_2.c @@ -0,0 +1,20 @@ +#include + +int total; /* total of all the numbers */ +int current; /* current value from the user */ +int counter; /* for loop counter */ + +char line[80]; /* Input from keyboard */ + +main() { + total = 0; + for (counter = 0; counter < 5; counter++) { + (void)printf("Number? "); + + (void)fgets(line, sizeof(line), stdin); + (void)sscanf(line, "%d", ¤t); + total += current; + } + (void)printf("The grand total is %d\n", total); + return (0); +} diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/07_3.c b/reference/C/CONTRIB/OR_PRACTICAL_C/07_3.c new file mode 100644 index 0000000..bf66eb7 --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/07_3.c @@ -0,0 +1,44 @@ +#include +char line[100]; /* line of text from input */ + +int result; /* the result of the calculations */ +char operator; /* operator the user specified */ +int value; /* value specified after the operator */ +main() +{ + result = 0; /* initialize the result */ + + /* loop forever (or until break reached) */ + while (1) { + (void) printf("Result: %d\n", result); + (void) printf("Enter operator and number: "); + + (void) fgets(line, sizeof(line), stdin); + (void) sscanf(line, "%c %d", &operator, &value); + + if ((operator == 'q') || (operator == 'Q')) + break; + switch (operator) { + case '+': + result += value; + break; + case '-': + result -= value; + break; + case '*': + result *= value; + break; + case '/': + if (value == 0) { + (void)printf("Error:Divide by zero\n"); + (void)printf(" operation ignored\n"); + } else + result /= value; + break; + default: + (void) printf("Unknown operator %c\n", operator); + break; + } + } + return (0); +} diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/08_1.c b/reference/C/CONTRIB/OR_PRACTICAL_C/08_1.c new file mode 100644 index 0000000..5cd2c0d --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/08_1.c @@ -0,0 +1,15 @@ +#include + +main() { + int counter; /* loop counter */ + for (counter = 0; counter < 3; counter++) { + int temporary = 1; + static int permanent = 1; + + (void)printf("Temporary %d Permanent %d\n", + temporary, permanent); + temporary++; + permanent++; + } + return (0); +} diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/08_2.c b/reference/C/CONTRIB/OR_PRACTICAL_C/08_2.c new file mode 100644 index 0000000..9adbad0 --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/08_2.c @@ -0,0 +1,30 @@ +#include + +main() +{ + /* Compute a triangle */ + float triangle(float width, float height); + + (void)printf("Triangle #1 %f\n", triangle(1.3, 8.3)); + (void)printf("Triangle #2 %f\n", triangle(4.8, 9.8)); + (void)printf("Triangle #3 %f\n", triangle(1.2, 2.O)); + return (0); +} + +/******************************************** + * triangle -- compute area of a triangle * + * * + * Parameters * + * width -- width of the triangle * + * height -- height of the triangle * + * * + * Returns * + * area of the triangle * + ********************************************/ +float triangle(float width, float height) +{ + float area; /* Area of the triangle */ + + area = width * height / 2.0; + return (area); +} diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/08_3.c b/reference/C/CONTRIB/OR_PRACTICAL_C/08_3.c new file mode 100644 index 0000000..839c008 --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/08_3.c @@ -0,0 +1,7 @@ +main() +{ + + init(); + solve_problems(); + finish_up(); +} diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/09_1.c b/reference/C/CONTRIB/OR_PRACTICAL_C/09_1.c new file mode 100644 index 0000000..805521b --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/09_1.c @@ -0,0 +1,13 @@ +int data[10]; /* some data */ +int twice[10]; /* twice some data */ + +main() +{ + int index; /* index into the data */ + + for (index = 0; index < 10; index++) { + data[index] = index; + twice[index] = index * 2; + } + return (0); +} diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/09_2.c b/reference/C/CONTRIB/OR_PRACTICAL_C/09_2.c new file mode 100644 index 0000000..22c4b2d --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/09_2.c @@ -0,0 +1,15 @@ +#define SIZE 20 /* work on 20 elements */ + +int data[SIZE]; /* some data */ +int twice[SIZE]; /* twice some data */ + +main() +{ + int index; /* index into the data */ + + for (index = 0; index < SIZE; index++) { + data[index] = index; + twice[index] = index * 2; + } + return (0); +} diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/09_3.c b/reference/C/CONTRIB/OR_PRACTICAL_C/09_3.c new file mode 100644 index 0000000..915ada7 --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/09_3.c @@ -0,0 +1,16 @@ +#define BIG_NUMBER 10 ** 10 + +main() +{ + /* index for our calculations */ + int index; + + index = 0; + + /* syntax error on next line */ + while (index < BIG_NUMBER) { + index = index * 8; + } + return (0); +} + diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/09_4.c b/reference/C/CONTRIB/OR_PRACTICAL_C/09_4.c new file mode 100644 index 0000000..cda0066 --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/09_4.c @@ -0,0 +1,13 @@ +#include +#define SQR(x) (x * x) + +main() +{ + int counter; /* counter for loop */ + + for (counter = 0; counter < 5; counter++) { + (void)printf("x %d, x squared %d\n", + counter+1, SQR(counter+1)); + } + return (0); +} diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/09_5.c b/reference/C/CONTRIB/OR_PRACTICAL_C/09_5.c new file mode 100644 index 0000000..6428f43 --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/09_5.c @@ -0,0 +1,13 @@ +#include +#define SQR(x) ((x) * (x)) + +main() +{ + int counter; /* counter for loop */ + + counter = 0; + while (counter < 5) + (void)printf("x %d square %d\n", + counter, SQR(counter++)); + return (0); +} diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/10_1.c b/reference/C/CONTRIB/OR_PRACTICAL_C/10_1.c new file mode 100644 index 0000000..3dac7ad --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/10_1.c @@ -0,0 +1,46 @@ +#include + +#define X_SIZE 40 /* size of array in the X direction */ +#define Y_SIZE 60 /* size of the array in Y direction */ +/* + * We use X_SIZE/8 since we pack 8 bits per byte + */ +char graphics[X_SIZE / 8][Y_SIZE]; /* the graphics data */ + +#define SET_BIT(x,y) graphics[(x)/8][y] |= (0x80 >>((x)%8)) + +main() +{ + int loc; /* current location we are setting */ + void print_graphics(void); /* print the data */ + + for (loc = 0; loc < X_SIZE; loc++) + SET_BIT(loc, loc); + + print_graphics(); + return (0); +} +/******************************************************** + * print_graphics -- print the graphics bit array * + * as a set of X and .'s. * + ********************************************************/ +void print_graphics(void) +{ + int x; /* current x BYTE */ + int y; /* current y location */ + int bit; /* bit we are testing in the current byte */ + + for (y = 0; y < Y_SIZE; y++) { + /* Loop for each byte in the array */ + for (x = 0; x < X_SIZE / 8; x++) { + /* Handle each bit */ + for (bit = 0x80; bit > 0; bit = (bit >> 1)) { + if ((graphics[x][y] & bit) != 0) + (void) printf("X"); + else + (void) printf("."); + } + } + (void) printf("\n"); + } +} diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/11_1.c b/reference/C/CONTRIB/OR_PRACTICAL_C/11_1.c new file mode 100644 index 0000000..cc1ce51 --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/11_1.c @@ -0,0 +1,19 @@ +/* + * Define a variable to hold an integer or + * a real number (but not both) + */ +union value { + long int i_value; /* The real number */ + float f_value; /* The floating-point number */ +} data; +int i; /* Random integer */ +float f; /* Random floating-point number */ +main() +{ + data.f_value = 5.0; + data.i_value = 3; /* data.f_value overwritten */ + i = data.i_value; /* legal */ + f = data.f_value; /* not legal, will generate unexpected results */ + data.f_value = 5.5; /* put something in f_value/clobber i_value */ + i = data.i_value; /* not legal, will generate unexpected results */ +} diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/12_1.c b/reference/C/CONTRIB/OR_PRACTICAL_C/12_1.c new file mode 100644 index 0000000..fa15a49 --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/12_1.c @@ -0,0 +1,18 @@ +#include +main() +{ + int thing_var; /* define a variable for thing */ + int *thing_ptr; /* define a pointer to thing */ + + thing_var = 2; /* assigning a value to thing */ + (void)printf("Thing %d\n", thing_var); + + thing_ptr = &thing_var; /* make the pointer point to thing */ + *thing_ptr = 3; /* thing_ptr points to thing_var so */ + /* thing_var changes to 3 */ + (void)printf("Thing %d\n", thing_var); + + /* another way of doing the printf */ + (void)printf("Thing %d\n", *thing_ptr); + return (0); +} diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/12_2.c b/reference/C/CONTRIB/OR_PRACTICAL_C/12_2.c new file mode 100644 index 0000000..1ca14c0 --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/12_2.c @@ -0,0 +1,17 @@ +#include +main() +{ + int count = 0; /* number of times through */ + + void inc_count(int *);/* update the counter */ + + while (count < 10) + inc_count(&count); + + return (0); +} + +void inc_count(int *count_ptr) +{ + (*count_ptr)++; +} diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/12_3.c b/reference/C/CONTRIB/OR_PRACTICAL_C/12_3.c new file mode 100644 index 0000000..f608eb3 --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/12_3.c @@ -0,0 +1,15 @@ +#define ARRAY_SIZE 10 /* Number of characters in array */ +/* Array to print */ +char array[ARRAY_SIZE] = "012345678"; + +main() +{ + int index; /* Index into the array */ + + for (index = 0; index < ARRAY_SIZE; index++) { + (void)printf( + "&array[index]=0x%x (array+index)=0x%x array[index]=0x%x\n", + &array[index], (array+index), array[index]); + } + return (0); +} diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/12_4.c b/reference/C/CONTRIB/OR_PRACTICAL_C/12_4.c new file mode 100644 index 0000000..608ac9f --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/12_4.c @@ -0,0 +1,15 @@ +#include + +int array[10] = {4, 5, 8, 9, 8, 1, 0, 1, 9, 3}; +int index; + +main() +{ + index = 0; + while (array[index] != 0) + index++; + + (void) printf("Number of elements before zero %d\n", + index); + return (0); +} diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/12_5.c b/reference/C/CONTRIB/OR_PRACTICAL_C/12_5.c new file mode 100644 index 0000000..f1db660 --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/12_5.c @@ -0,0 +1,16 @@ +#include + +int array[10] = {4, 5, 8, 9, 8, 1, 0, 1, 9, 3}; +int *array_ptr; + +main() +{ + array_ptr = array; + + while ((*array_ptr) != 0) + array_ptr++; + + (void) printf("Number of elements before zero %d\n", + array_ptr - array); + return (0); +} diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/12_6.c b/reference/C/CONTRIB/OR_PRACTICAL_C/12_6.c new file mode 100644 index 0000000..7667200 --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/12_6.c @@ -0,0 +1,50 @@ +#define MAX 10 +main() +{ + int array[MAX]; + + void init_array_1(); + void init_array_2(); + + /* one way of initializing the array */ + init_array_1(array); + + /* another way of initializing the array */ + init_array_1(&array[0]); + + /* works, but the compiler generates a warning */ + init_array_1(&array); + + /* Similar to the first method but */ + /* function is different */ + init_array_2(array); + + return (0); +} +/******************************************************** + * init_array_1 -- Zero out an array * + * * + * Parameters * + * data -- the array to zero * + ********************************************************/ +void init_array_1(int data[]) +{ + int index; + + for (index = 0; index < MAX; index++) + data[index] = 0; +} + +/******************************************************** + * init_array_2 -- Zero out an array * + * * + * Parameters * + * data_ptr -- pointer to array to zero * + ********************************************************/ +void init_array_2(int *data_ptr) +{ + int index; + + for (index = 0; index < MAX; index++) + *(data_ptr + index) = 0; +} diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/12_7.c b/reference/C/CONTRIB/OR_PRACTICAL_C/12_7.c new file mode 100644 index 0000000..aac1173 --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/12_7.c @@ -0,0 +1,65 @@ +/******************************************************** + * split -- split an entry of the form Last/First * + * into two parts. * + ********************************************************/ +#include +#include + +/* Our version of the library function */ +char *strchr(char *, char); + +main() +{ + char line[80]; /* The input line */ + char *first_ptr; /* pointer to the first name */ + char *last_ptr; /* pointer to the last name */ + + (void)fgets(line, sizeof(line), stdin); + + /* Get rid of trailing newline */ + line[strlen(line)-1] = '\0'; + + last_ptr = line; /* last name is at beginning of line */ + + first_ptr = strchr(line, '/'); /* Find slash */ + + /* Check for an error */ + if (first_ptr == NULL) { + (void)fprintf(stderr, + "Error: Unable to find slash in %s\n", line); + exit (8); + } + + *first_ptr = '\0'; /* Zero out the slash */ + + first_ptr++; /* Move to first character of name */ + + (void)printf("First:%s Last:%s\n", first_ptr, last_ptr); + return (0); +} +/******************************************************** + * strchr -- find a character in a string * + * Duplicate of a standard library function, * + * put here for illustrative purposes. * + * * + * Parameters * + * string_ptr -- string to look through * + * find -- character to find * + * * + * Returns * + * pointer to 1st occurrence of character * + * in string or NULL for error * + ********************************************************/ +char *strchr(char * string_ptr, char find) +{ + while (*string_ptr != find) { + + /* Check for end */ + + if (*string_ptr == '\0') + return (NULL); /* not found */ + + string_ptr++; + } + return (string_ptr); /* Found */ +} diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/12_8.c b/reference/C/CONTRIB/OR_PRACTICAL_C/12_8.c new file mode 100644 index 0000000..500683b --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/12_8.c @@ -0,0 +1,103 @@ +/******************************************************** + * print -- format files for printing * + ********************************************************/ +#include +#include /* ANSI Standard only */ + +int verbose = 0; /* verbose mode (default = false) */ +char *out_file = "print.out"; /* output filename */ +char *program_name; /* name of the program (for errors) */ +int line_max = 66; /* number of lines per page */ + +main(int argc, char *argv[]) +{ + void do_file(char *); /* print a file */ + void usage(void); /* tell user how to use the program */ + + /* save the program name for future use */ + program_name = argv[0]; + + /* + * loop for each option. + * Stop if we run out of arguments + * or we get an argument without a dash. + */ + while ((argc > 1) && (argv[1][0] == '-')) { + /* + * argv[1][1] is the actual option character. + */ + switch (argv[1][1]) { + /* + * -v verbose + */ + case 'v': + verbose = 1; + break; + /* + * -o output file + * [0] is the dash + * [1] is the "o" + * [2] starts the name + */ + case 'o': + out_file = &argv[1][2]; + break; + /* + * -l set max number of lines + */ + case 'l': + line_max = atoi(&argv[1][2]); + break; + default: + (void)fprintf(stderr,"Bad option %s\n", argv[1]); + usage(); + } + /* + * move the argument list up one + * move the count down one + */ + argv++; + argc--; + } + + /* + * At this point all the options have been processed. + * Check to see if we have no files in the list + * and if so, we need to process just standard in. + */ + if (argc == 1) { + do_file("print.in"); + } else { + while (argc > 1) { + do_file(argv[1]); + argv++; + argc--; + } + } + return (0); +} +/******************************************************** + * do_file -- dummy routine to handle a file * + * * + * Parameter * + * name -- name of the file to print * + ********************************************************/ +void do_file(char *name) +{ + (void)printf("Verbose %d Lines %d Input %s Output %s\n", + verbose, line_max, name, out_file); +} +/******************************************************** + * usage -- tell the user how to use this program and * + * exit * + ********************************************************/ +void usage(void) +{ + (void)fprintf(stderr,"Usage is %s [options] [file-list]\n", + program_name); + (void)fprintf(stderr,"Options\n"); + (void)fprintf(stderr," -v verbose\n"); + (void)fprintf(stderr," -l Number of lines\n"); + (void)fprintf(stderr," -o Set output filename\n"); + exit (8); +} diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/13_1.c b/reference/C/CONTRIB/OR_PRACTICAL_C/13_1.c new file mode 100644 index 0000000..4f44233 --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/13_1.c @@ -0,0 +1,30 @@ +#include +#define FILE_NAME "input.txt" +#include /* ANSI Standard C file */ + +main() +{ + int count = 0; /* number of characters seen */ + FILE *in_file; /* input file */ + + /* character or EOF flag from input */ + int ch; + + in_file = fopen(FILE_NAME, "r"); + if (in_file == NULL) { + (void)printf("Can not open %s\n", FILE_NAME); + exit(8); + } + + while (1) { + ch = fgetc(in_file); + if (ch == EOF) + break; + count++; + } + (void) printf("Number of characters in %s is %d\n", + FILE_NAME, count); + + (void) fclose(in_file); + return (0); +} diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/13_2.c b/reference/C/CONTRIB/OR_PRACTICAL_C/13_2.c new file mode 100644 index 0000000..a1dd50c --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/13_2.c @@ -0,0 +1,70 @@ +/**************************************** + * copy -- copy one file to another. * + * * + * Usage * + * copy * + * * + * -- the file to copy from * + * -- the file to copy into * + ****************************************/ +#include +#ifndef __MSDOS__ /* if we are not MS-DOS */ +#define __UNIX__ /* then we are UNIX */ +#endif __MSDOS__ + +#include /* ANSI Standard C file */ + +#ifdef __UNIX__ +#include /* file defines for UNIX filesystem */ +#include +#include +#endif __UNIX__ + +#ifdef __MSDOS__ +#include /* file defines for DOS filesystem */ +#include +#include +#endif __MSDOS__ + +void exit(); /* lib routine */ + +#define BUFFER_SIZE (16 * 1024) /* use 16K buffers */ + +main(int argc, char *argv[]) +{ + char buffer[BUFFER_SIZE]; /* buffer for data */ + int in_file; /* input file descriptor */ + int out_file; /* output file descriptor */ + int read_size; /* number of bytes on last read */ + + if (argc != 3) { + (void) fprintf(stderr, "Error:Wrong number of arguments\n"); + (void) fprintf(stderr, "Usage is: copy \n"); + exit(8); + } + in_file = open(argv[1], O_RDONLY); + if (in_file < 0) { + (void) fprintf("Error:Unable to open %s\n", argv[1]); + exit(8); + } + out_file = open(argv[2], O_WRONLY | O_TRUNC | O_CREAT, 0666); + if (out_file < 0) { + (void) fprintf("Error:Unable to open %s\n", argv[2]); + exit(8); + } + while (1) { + read_size = read(in_file, buffer, sizeof(buffer)); + + if (read_size == 0) + break; /* end of file */ + + if (read_size < 0) { + (void) fprintf(stderr, "Error:Read error\n"); + exit(8); + } + (void) write(out_file, buffer, (unsigned int) read_size); + } + (void) close(in_file); + (void) close(out_file); + return (0); +} diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/14_01.c b/reference/C/CONTRIB/OR_PRACTICAL_C/14_01.c new file mode 100644 index 0000000..43c1937 --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/14_01.c @@ -0,0 +1,70 @@ +/******************************************************** + * Database -- A very simple database program to * + * look up names in a hardcoded list. * + * * + * Usage: * + * database * + * Program will ask you for a name. * + * Enter the name; it will tell you if * + * it is the list. * + * * + * A blank name terminates the program. * + ********************************************************/ +#define STRING_LENGTH 80 /* Length of typical string */ +#include + +main() +{ + char name[STRING_LENGTH]; /* a name to lookup */ + + int lookup(char *); /* lookup a name */ + + while (1) { + (void)printf("Enter name: "); + (void)fgets(name, sizeof(name), stdin); + + /* Check for blank name */ + /* (remember 1 character for newline) */ + if (strlen(name) <= 1) + break; + + /* Get rid of newline */ + name[strlen(name)-1] = '\0'; + + if (lookup(name)) + (void)printf("%s is in the list\n", name); + else + (void)printf("%s is not in the list\n", name); + } + return (0); +} +/******************************************************** + * lookup -- lookup a name in a list * + * * + * Parameters * + * name -- name to lookup * + * * + * Returns * + * 1 -- name in the list * + * 0 -- name not in the list * + ********************************************************/ +int lookup(char *name) +{ + /* List of people in the database */ + /* Note: Last name is a NULL for end of list */ + static char *list[] = { + "John", + "Jim", + "Jane", + "Clyde", + NULL + }; + + int index; /* index into list */ + + for (index = 0; list[index] != NULL; index++) { + if (strcmp(list[index], name) == 0) + return (1); + } + return (0); +} diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/14_02.c b/reference/C/CONTRIB/OR_PRACTICAL_C/14_02.c new file mode 100644 index 0000000..a88a33d --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/14_02.c @@ -0,0 +1,34 @@ +#include +/* + * The main program will open this file if -S is on + * the command line. + */ +FILE *save_file = NULL; +/******************************************************** + * extended_fgets -- get a line from the input file * + * and record it in a save file if needed. * + * * + * Parameters * + * line -- the line to read * + * size -- sizeof(line) -- maximum number of * + * characters to read * + * file -- file to read data from * + * (normally stdin) * + * * + * Returns * + * NULL -- error or end of file in read * + * otherwise line (just like fgets) * + ********************************************************/ +char *extended_fgets(char *line, int size, FILE *file) +{ + + char *result; /* result of fgets */ + + result = fgets(line, size, file); + + /* did someone ask for a save file */ + if (save_file != NULL) + (void)fputs(line, save_file); + + return (result); +} diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/14_03.c b/reference/C/CONTRIB/OR_PRACTICAL_C/14_03.c new file mode 100644 index 0000000..0c9151b --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/14_03.c @@ -0,0 +1,52 @@ +/******************************************************** + * Database -- A very simple database program to * + * lookup names in a hardcoded list. * + * * + * Usage: * + * database [-S] * + * * + * -S Specify save file for * + * debugging purposes * + * * + * Program will ask you for a name. * + * Enter the name; it will tell you if * + * it is the list. * + * * + * A blank name terminates the program. * + ********************************************************/ +#include + +FILE *save_file = NULL; /* Save file if any */ +char *extended_fgets(char *, int, FILE *); + +main(int argc, char *argv[]) +{ + char name[80]; /* a name to lookup */ + char *save_file_name; /* Name of the save file */ + + int lookup(char *); /* lookup a name */ + + while ((argc > 1) && (argv[1][0] == '-')) { + switch (argv[1][1]) { + case 'S': + save_file_name = &argv[1][2]; + save_file = fopen(save_file_name, "w"); + if (save_file == NULL) + (void)fprintf(stderr, + "Warning:Unable to open save file %s\n", + save_file_name); + break; + default: + (void)fprintf(stderr,"Bad option: %s\n", argv[1]); + exit (8); + } + argc--; + argv++; + } + + + while (1) { + (void)printf("Enter name: "); + (void)extended_fgets(name, sizeof(name), stdin); + + /* ... Rest of program ... */ diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/14_04.c b/reference/C/CONTRIB/OR_PRACTICAL_C/14_04.c new file mode 100644 index 0000000..ca5c709 --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/14_04.c @@ -0,0 +1,38 @@ +#include +FILE *save_file = NULL; /* Save input in this file */ +FILE *playback_file = NULL; /* Playback data from this file */ +/******************************************************** + * extended_fgets -- get a line from the input file * + * and record it in a save file if needed * + * * + * Parameters * + * line -- the line to read * + * size -- sizeof(line) -- maximum number of * + * characters to read * + * file -- file to read data from * + * (normally stdin) * + * * + * Returns * + * NULL -- error or end of file in read * + * otherwise line (just like fgets) * + ********************************************************/ +char *extended_fgets(char *line, int size, FILE *file) +{ + extern FILE *save_file; /* file to save strings in */ + extern FILE *playback_file; /* file for alternate input */ + + char *result; /* result of fgets */ + + if (playback_file != NULL) { + result = fgets(line, size, file); + /* echo the input to the standard out so the user sees it */ + (void)fputs(line, stdout); + } else + result = fgets(line, size, file); + + /* did someone ask for a save file */ + if (save_file != NULL) + (void)fputs(line, save_file); + + return (result); +} diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/14_05.c b/reference/C/CONTRIB/OR_PRACTICAL_C/14_05.c new file mode 100644 index 0000000..5e04459 --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/14_05.c @@ -0,0 +1,63 @@ +/******************************************************** + * Database -- A very simple database program to * + * lookup names in a hardcoded list. * + * * + * Usage: * + * database [-S] [-P] * + * * + * -S Specify save file for * + * debugging purposes. * + * * + * -P Specify playback file for * + * debugging or demonstration. * + * * + * * + * Program will ask you for a name. * + * Enter the name; it will tell you if * + * it is the list. * + * * + * A blank name terminates the program. * + ********************************************************/ +#include + +FILE *save_file = NULL; /* Save file if any */ +FILE *playback_file = NULL; /* Playback file if any */ +char *extended_fgets(char *, int, FILE *); + +main(int argc, char *argv[]) +{ + char name[80]; /* a name to lookup */ + char *save_file_name; /* Name of the save file */ + char *playback_file_name; /* Name of the playback file */ + + int lookup(char *); /* lookup a name */ + + while ((argc > 1) && (argv[1][0] == '-')) { + switch (argv[1][1]) { + case 'S': + save_file_name = &argv[1][2]; + save_file = fopen(save_file_name, "w"); + if (save_file == NULL) + (void)fprintf(stderr, + "Warning:Unable to open save file %s\n", + save_file_name); + break; + case 'P': + playback_file_name = &argv[1][2]; + playback_file = fopen(playback_file_name, "r"); + if (playback_file == NULL) { + (void)fprintf(stderr, + "Error:Unable to open playback file %s\n", + playback_file_name); + exit (8); + } + break; + default: + (void)fprintf(stderr,"Bad option: %s\n", argv[1]); + exit (8); + } + argc--; + argv++; + } + + /* ... rest of program ... */ diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/14_06.c b/reference/C/CONTRIB/OR_PRACTICAL_C/14_06.c new file mode 100644 index 0000000..5dca028 --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/14_06.c @@ -0,0 +1,37 @@ +#include +int seven_count; /* number of seven's in the data */ +int data[5]; /* the data to count 3 and 7 in */ +int three_count; /* the number of threes in the data */ + +main() { + int index; /* index into the data */ + void get_data(int data[]); + + seven_count = 0; + three_count = 0; + get_data(data); + + for (index = 1; index <= 5; index++) { + if (data[index] == 3) + three_count++; + if (data[index] == 7) + seven_count++; + } + (void)printf("Three's %d Seven's %d\n", + three_count, seven_count); + return (0); +} +/******************************************************** + * get_data -- get 5 numbers from the command line * + ********************************************************/ +void get_data(int data[]) +{ + char line[100]; /* line of input */ + + (void)printf("Enter 5 numbers\n"); + (void)fgets(line, sizeof(line), stdin); + (void)sscanf(line, "%d %d %d %d %d", + &data[1], &data[2], &data[3], + &data[4], &data[5]); +} + diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/14_07.c b/reference/C/CONTRIB/OR_PRACTICAL_C/14_07.c new file mode 100644 index 0000000..e2a5b52 --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/14_07.c @@ -0,0 +1,76 @@ +/******************************************************** + * search -- Search a set of numbers. * + * * + * Usage: * + * search * + * you will be asked numbers to lookup * + * * + * Files: * + * numbers.dat -- numbers 1 per line to search * + * (Numbers must be ordered) * + ********************************************************/ +#include +#define MAX_NUMBERS 1000 /* Max numbers in file */ +#define DATA_FILE "numbers.dat" /* File with numbers */ + +int data[MAX_NUMBERS]; /* Array of numbers to search */ +int max_count; /* Number of valid elements in data */ +main() +{ + FILE *in_file; /* Input file */ + int middle; /* Middle of our search range */ + int low, high; /* Upper/lower bound */ + int search; /* number to search for */ + char line[80]; /* Input line */ + + in_file = fopen(DATA_FILE, "r"); + if (in_file == NULL) { + (void)fprintf(stderr,"Error:Unable to open %s\n", DATA_FILE); + exit (8); + } + + /* + * Read in data + */ + + max_count = 0; + while (1) { + if (fgets(line, sizeof(line), in_file) == NULL) + break; + + /* convert number */ + (void)sscanf(line, "%d", data[max_count]); + max_count++; + } + + while (1) { + (void)printf("Enter number to search for or -1 to quit:" ); + (void)fgets(line, sizeof(line), stdin); + (void)sscanf(line, "%d", &search); + + if (search == -1) + break; + + low = 0; + high = max_count; + + while (1) { + middle = (low + high) / 2; + + if (data[middle] == search) { + (void)printf("Found at index %d\n", middle); + } + + if (low == high) { + (void)printf("Not found\n"); + break; + } + + if (data[middle] < search) + low = middle; + else + high = middle; + } + } + return (0); +} diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/14_08.c b/reference/C/CONTRIB/OR_PRACTICAL_C/14_08.c new file mode 100644 index 0000000..917c702 --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/14_08.c @@ -0,0 +1,77 @@ +/******************************************************** + * search -- Search a set of numbers. * + * * + * Usage: * + * search * + * you will be asked numbers to lookup * + * * + * Files: * + * numbers.dat -- numbers 1 per line to search * + * (Numbers must be ordered) * + ********************************************************/ +#include +#define MAX_NUMBERS 1000 /* Max numbers in file */ +#define DATA_FILE "numbers.dat" /* File with numbers */ + +int data[MAX_NUMBERS]; /* Array of numbers to search */ +int max_count; /* Number of valid elements in data */ +main() +{ + FILE *in_file; /* Input file */ + int middle; /* Middle of our search range */ + int low, high; /* Upper/lower bound */ + int search; /* number to search for */ + char line[80]; /* Input line */ + + in_file = fopen(DATA_FILE, "r"); + if (in_file == NULL) { + (void)fprintf(stderr,"Error:Unable to open %s\n", DATA_FILE); + exit (8); + } + + /* + * Read in data + */ + + max_count = 0; + while (1) { + if (fgets(line, sizeof(line), in_file) == NULL) + break; + + /* convert number */ + (void)sscanf(line, "%d", &data[max_count]); + max_count++; + } + + while (1) { + (void)printf("Enter number to search for or -1 to quit:" ); + (void)fgets(line, sizeof(line), stdin); + (void)sscanf(line, "%d", &search); + + if (search == -1) + break; + + low = 0; + high = max_count; + + while (1) { + if (low >= high) { + (void)printf("Not found\n"); + break; + } + + middle = (low + high) / 2; + + if (data[middle] == search) { + (void)printf("Found at index %d\n", middle); + break; + } + + if (data[middle] < search) + low = middle +1; + else + high = middle -1; + } + } + return (0); +} diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/14_09.c b/reference/C/CONTRIB/OR_PRACTICAL_C/14_09.c new file mode 100644 index 0000000..6ca905d --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/14_09.c @@ -0,0 +1,12 @@ + +float point_color(point_number) +int point_number; +{ + float correction; /* color correction factor */ + extern float red,green,blue;/* current colors */ + + correction = lookup(point_number); + return (red*correction * 100.0 + + blue*correction * 10.0 + + green*correction); +} diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/14_10.c b/reference/C/CONTRIB/OR_PRACTICAL_C/14_10.c new file mode 100644 index 0000000..987b213 --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/14_10.c @@ -0,0 +1,13 @@ +#include +main() +{ + int i,j; /* two random integers */ + + i = 1; + j = 0; + (void)printf("Starting\n"); + (void)printf("Before divide..."); + i = i / j; /* divide by zero error */ + (void)printf("After\n"); + return(0); +} diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/14_11.c b/reference/C/CONTRIB/OR_PRACTICAL_C/14_11.c new file mode 100644 index 0000000..b3f2233 --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/14_11.c @@ -0,0 +1,16 @@ +#include +main() +{ + int i,j; /* two random integers */ + + i = 1; + j = 0; + (void)printf("Starting\n"); + (void)fflush(stdout); + (void)printf("Before divide..."); + (void)fflush(stdout); + i = i / j; /* divide by zero error */ + (void)printf("After\n"); + (void)fflush(stdout); + return(0); +} diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/14_12.c b/reference/C/CONTRIB/OR_PRACTICAL_C/14_12.c new file mode 100644 index 0000000..c97d54e --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/14_12.c @@ -0,0 +1,15 @@ +#define X_SIZE 60 +#define Y_SIZE 30 + +int matrix[X_SIZE][Y_SIZE]; + +void init_matrix(void) +{ + int x,y; /* current element to zero */ + + for (x = 0; x < X_SIZE; x++) { + for (y = 0; y < Y_SIZE; y++) { + matrix[x][y] = -1; + } + } +} diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/14_13.c b/reference/C/CONTRIB/OR_PRACTICAL_C/14_13.c new file mode 100644 index 0000000..0f7c4dd --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/14_13.c @@ -0,0 +1,15 @@ +#define X_SIZE 60 +#define Y_SIZE 30 + +int matrix[X_SIZE][Y_SIZE]; + +void init_matrix(void) +{ + register int x,y; /* current element to zero */ + + for (x = 0; x < X_SIZE; x++) { + for (y = 0; y < Y_SIZE; y++) { + matrix[x][y] = -1; + } + } +} diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/14_14.c b/reference/C/CONTRIB/OR_PRACTICAL_C/14_14.c new file mode 100644 index 0000000..01a45bb --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/14_14.c @@ -0,0 +1,15 @@ +#define X_SIZE 60 +#define Y_SIZE 30 + +int matrix[X_SIZE][Y_SIZE]; + +void init_matrix(void) +{ + register int x,y; /* current element to zero */ + + for (y = 0; y < Y_SIZE; y++) { + for (x = 0; x < X_SIZE; x++) { + matrix[x][y] = -1; + } + } +} diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/14_15.c b/reference/C/CONTRIB/OR_PRACTICAL_C/14_15.c new file mode 100644 index 0000000..441b2f2 --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/14_15.c @@ -0,0 +1,15 @@ +#define X_SIZE 60 +#define Y_SIZE 32 + +int matrix[X_SIZE][Y_SIZE]; + +void init_matrix(void) +{ + register int x,y; /* current element to zero */ + + for (y = 0; y < Y_SIZE; y++) { + for (x = 0; x < X_SIZE; x++) { + matrix[x][y] = -1; + } + } +} diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/14_16.c b/reference/C/CONTRIB/OR_PRACTICAL_C/14_16.c new file mode 100644 index 0000000..5b040e4 --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/14_16.c @@ -0,0 +1,16 @@ +#define X_SIZE 60 +#define Y_SIZE 30 + +int matrix[X_SIZE][Y_SIZE]; + +void init_matrix(void) +{ + register int index; /* element counter */ + register int *matrix_ptr; + + matrix_ptr = &matrix[0][0]; + for (index = 0; index < X_SIZE * Y_SIZE; index++) { + *matrix_ptr = -1; + matrix_ptr++; + } +} diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/14_17.c b/reference/C/CONTRIB/OR_PRACTICAL_C/14_17.c new file mode 100644 index 0000000..d7e1fd7 --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/14_17.c @@ -0,0 +1,16 @@ +#define X_SIZE 60 +#define Y_SIZE 30 + +int matrix[X_SIZE][Y_SIZE]; + +void init_matrix(void) +{ + register int *matrix_ptr; + + for (matrix_ptr = &matrix[0][0]; + matrix_ptr <= &matrix[X_SIZE-1][Y_SIZE-1]; + matrix_ptr++) { + + *matrix_ptr = -1; + } +} diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/14_18.c b/reference/C/CONTRIB/OR_PRACTICAL_C/14_18.c new file mode 100644 index 0000000..1924966 --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/14_18.c @@ -0,0 +1,8 @@ +#define X_SIZE 60 +#define Y_SIZE 30 + +int matrix[X_SIZE][Y_SIZE]; +void init_matrix(void) +{ + (void)memset(matrix, -1, sizeof(matrix)); +} diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/14_19.c b/reference/C/CONTRIB/OR_PRACTICAL_C/14_19.c new file mode 100644 index 0000000..1fa8b50 --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/14_19.c @@ -0,0 +1,7 @@ +#define X_SIZE 60 +#define Y_SIZE 30 + +int matrix[X_SIZE][Y_SIZE]; + +#define init_matrix() \ + (void)memset(matrix, -1, sizeof(matrix)); diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/15_1.c b/reference/C/CONTRIB/OR_PRACTICAL_C/15_1.c new file mode 100644 index 0000000..69ecdef --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/15_1.c @@ -0,0 +1,31 @@ +#include +main() +{ + /* two numbers to work with */ + float number1, number2; + float result; /* result of calculation */ + int counter; /* loop counter and accuracy check */ + + number1 = 1.0; + number2 = 1.0; + counter = 0; + + while (number1 + number2 != number1) { + counter++; + number2 = number2 / 10.0; + } + (void) printf("%2d digits accuracy in calculations\n", counter); + + number2 = 1.0; + counter = 0; + + while (1) { + result = number1 + number2; + if (result == number1) + break; + counter++; + number2 = number2 / 10.0; + } + (void) printf("%2d digits accuracy in storage\n", counter); + return (0); +} diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/16_1.c b/reference/C/CONTRIB/OR_PRACTICAL_C/16_1.c new file mode 100644 index 0000000..6f2c0f2 --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/16_1.c @@ -0,0 +1,6 @@ +#include /* using ANSI C standard libraries */ +main() +{ + char *string_ptr; + + string_ptr = malloc(80); diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/16_2.c b/reference/C/CONTRIB/OR_PRACTICAL_C/16_2.c new file mode 100644 index 0000000..37dbc5f --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/16_2.c @@ -0,0 +1,27 @@ +/******************************************************** + * find -- look for a data item in the list * + * * + * Parameters * + * name -- name to look for in the list * + * * + * Returns * + * 1 if name is found * + * 0 if name is not found * + ********************************************************/ +int file(char *name) +{ + /* current structure we are looking at */ + struct linked_list *current_ptr; + + current_ptr = first_ptr; + + while ((strcmp(current_ptr->data, name) != 0) && + (current_ptr != NULL)) + current_ptr = current_ptr->next_ptr; + + /* + * If current_ptr is null, we fell off the end of the list and + * didn't find the name + */ + return (current_ptr != NULL); +} diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/16_3.c b/reference/C/CONTRIB/OR_PRACTICAL_C/16_3.c new file mode 100644 index 0000000..958e544 --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/16_3.c @@ -0,0 +1,159 @@ +/******************************************************** + * words -- scan a file and print out a list of words * + * in ASCII order. * + * * + * Usage: * + * words * + ********************************************************/ +#include +#include +#include +#include /* ANSI Standard only */ + +struct node { + struct node *right; /* tree to the right */ + struct node *left; /* tree to the left */ + char *word; /* word for this tree */ +}; + +/* the top of the tree */ +static struct node *root = NULL; + +main(int argc, char *argv[]) +{ + void scan(char *); /* scan the files for words */ + void print_tree(struct node *);/* print the words in the file */ + + if (argc != 2) { + (void) fprintf(stderr, "Error:Wrong number of parameters\n"); + (void) fprintf(stderr, " on the command line\n"); + (void) fprintf(stderr, "Usage is:\n"); + (void) fprintf(stderr, " words 'file'\n"); + exit(8); + } + scan(argv[1]); + print_tree(root); + return (0); +} +/******************************************************** + * scan -- scan the file for words * + * * + * Parameters * + * name -- name of the file to scan * + ********************************************************/ +void scan(char *name) +{ + char word[100]; /* word we are working on */ + int index; /* index into the word */ + int ch; /* current character */ + FILE *in_file; /* input file */ + + /* enter a word into the tree */ + void enter(struct node **, char *); + + in_file = fopen(name, "r"); + if (in_file == NULL) { + (void) fprintf(stderr, + "Error:Unable to open %s\n", name); + exit(8); + } + while (1) { + /* scan past the whitespace */ + while (1) { + ch = fgetc(in_file); + + if (isalpha(ch) || (ch == EOF)) + break; + } + + if (ch == EOF) + break; + + word[0] = ch; + for (index = 1; index < sizeof(word); index++) { + ch = fgetc(in_file); + if (!isalpha(ch)) + break; + word[index] = ch; + } + /* put a null on the end */ + word[index] = '\0'; + + enter(&root, word); + } + (void) fclose(in_file); +} +/******************************************************** + * enter -- enter a word into the tree * + * * + * Parameters * + * node -- current node we are looking at * + * word -- word to enter * + ********************************************************/ +void enter(struct node **node, char *word) +{ + int result; /* result of strcmp */ + + char *save_string(char *); /* save a string on the heap */ + void memory_error(void); /* tell user no more room */ + + /* see if we have reached the end */ + if ((*node) == NULL) { + (*node) = (struct node *) malloc(sizeof(struct node)); + if ((*node) == NULL) + memory_error(); + (*node)->left = NULL; + (*node)->right = NULL; + (*node)->word = save_string(word); + } + result = strcmp((*node)->word, word); + if (result == 0) + return; + if (result < 0) + enter(&(*node)->right, word); + else + enter(&(*node)->left, word); +} +/******************************************************** + * save_string -- save a string on the heap * + * * + * Parameters * + * string -- string to save * + * * + * Returns * + * pointer to malloc-ed section of memory with * + * the string copied into it. * + ********************************************************/ +char *save_string(char *string) +{ + char *new_string; /* where we are going to put string */ + + new_string = malloc((unsigned) (strlen(string) + 1)); + if (new_string == NULL) + memory_error(); + (void) strcpy(new_string, string); + return (new_string); +} +/******************************************************** + * memory_error -- write error and die * + ********************************************************/ +void memory_error(void) +{ + (void) fprintf(stderr, "Error:Out of memory\n"); + exit(8); +} +/******************************************************** + * print_tree -- print out the words in a tree * + * * + * Parameters * + * top -- the root of the tree to print * + ********************************************************/ +void print_tree(struct node *top) +{ + if (top == NULL) + return; /* short tree */ + + print_tree(top->left); + (void) printf("%s\n", top->word); + print_tree(top->right); +} diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/17_1.c b/reference/C/CONTRIB/OR_PRACTICAL_C/17_1.c new file mode 100644 index 0000000..f0f68c9 --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/17_1.c @@ -0,0 +1,117 @@ +/******************************************************** + * infinite-array -- routines to handle infinite arrays * + * * + * An infinite array is an array that grows as needed. * + * There is no index too large for an infinite array * + * (unless we run out of memory). * + ********************************************************/ +#include "ia.h" /* get common definitions */ +#include +#include /* ANSI Standard only */ + +/* + * the following three variables implement + * a very simple pointer cache + * + * They store information on the last infinite array used, + * the last bucket we had and the last index used + * + * They are initialized to values we know will never + * be used by any real array. + */ +static struct infinite_array *cache_array_ptr = NULL; +static struct infinite_array *cache_bucket_ptr = NULL; +static int cache_index = -1; +/******************************************************** + * ia_store -- store an element into an infinite array. * + * * + * Parameters * + * array_ptr -- pointer to the array to use * + * index -- index into the array * + * store_data -- data to store * + ********************************************************/ +void ia_store(struct infinite_array * array_ptr, + int index, float store_data) +{ + /* pointer to the current bucket */ + struct infinite_array *current_ptr; + int current_index; /* index into the current bucket */ + + /* get the location in an infinite array cell */ + struct infinite_array *ia_locate( + struct infinite_array *, int, int *); + + current_ptr = ia_locate(array_ptr, index, ¤t_index); + current_ptr->data[current_index] = store_data; +} +/******************************************************** + * ia_get -- get an element from an infinite array. * + * * + * Parameters * + * array_ptr -- pointer to the array to use * + * index -- index into the array * + * * + * Returns * + * the value of the element * + ********************************************************/ +float ia_get(struct infinite_array *array_ptr, int index) +{ + /* pointer to the current bucket */ + struct infinite_array *current_ptr; + int current_index; /* index into the current bucket */ + + /* get the location an infinite array cell */ + struct infinite_array *ia_locate(); + + current_ptr = ia_locate(array_ptr, index, ¤t_index); + return (current_ptr->data[current_index]); +} +/******************************************************** + * ia_locate -- get the location of an infinite array * + * element. * + * * + * Parameters * + * array_ptr -- pointer to the array to use * + * index -- index into the array * + * current_index -- pointer to the index into this * + * bucket (returned) * + * * + * Returns * + * pointer to the current bucket * + ********************************************************/ +static struct infinite_array ia_locate( + struct infinite_array *array_ptr, int index + int *current_index_ptr) +{ + /* pointer to the current bucket */ + struct infinite_array *current_ptr; + + /* see if the cache will do us any good */ + if ((cache_array_ptr == array_ptr) && (index >= cache_index)) { + current_ptr = cache_bucket_ptr; + *current_index_ptr = index - cache_index; + } else { + current_ptr = array_ptr; + *current_index_ptr = index; + } + + while (*current_index_ptr > BLOCK_SIZE) { + if (current_ptr->next == NULL) { + current_ptr->next = + (struct infinite_array *) + malloc(sizeof(struct infinite_array)); + if (current_ptr->next == NULL) { + (void) fprintf(stderr, "Error:Out of memory\n"); + exit(8); + } + } + current_ptr = current_ptr->next; + *current_index_ptr -= BLOCK_SIZE; + } + + cache_index = index - (index % BLOCK_SIZE); + cache_array_ptr = array_ptr; + cache_bucket_ptr = current_ptr; + + return (current_ptr); +} diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/17_2.c b/reference/C/CONTRIB/OR_PRACTICAL_C/17_2.c new file mode 100644 index 0000000..57fdeae --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/17_2.c @@ -0,0 +1,142 @@ +/******************************************************** + * hist -- generate a histogram of an array of numbers * + * * + * Usage * + * hist * + * * + * Where * + * file is the name of the file to work on * + ********************************************************/ +#include "ia.h" +#include +#include /* ANSI Standard only */ +#include +/* + * the following definitions define the histogram + */ +#define NUMBER_OF_LINES 50 +#define LOW_BOUND 0.0 +#define HIGH_BOUND 99.0 +/* + * if we have NUMBER_OF_LINES data to + * output then each item must use + * the following factor + */ +#define FACTOR \ + ((HIGH_BOUND - LOW_BOUND) / ((float) (NUMBER_OF_LINES-1))) + +/* number of characters wide to make the histogram */ +#define WIDTH 60 + +static struct infinite_array data_array; +static int data_items; + +main(int argc, char *argv[]) +{ + void read_data(char *); /* get the data into the array */ + void print_histogram(void);/* print the data */ + + if (argc != 2) { + (void) fprintf(stderr, + "Error:Wrong number of arguments\n"); + (void) fprintf(stderr, + "Usage is:\n"); + (void) fprintf(stderr, + " hist \n"); + exit(8); + } + ia_init(&data_array); + data_items = 0; + + read_data(argv[1]); + print_histogram(); + return (0); +} +/******************************************************** + * read_data -- read data from the input file into * + * the data_array. * + * * + * Parameters * + * name -- the name of the file to read * + ********************************************************/ +void read_data(char *name) +{ + char line[100]; /* line from input file */ + FILE *in_file; /* input file */ + float data; /* data from input */ + + in_file = fopen(name, "r"); + if (in_file == NULL) { + (void) fprintf(stderr, + "Error:Unable to open %s\n", name); + exit(8); + } + while (1) { + if (fgets(line, sizeof(line), in_file) == NULL) + break; + + if (sscanf(line, "%f", &data) != 1) { + (void) fprintf(stderr, + "Error: Input data not floating point number\n"); + (void) fprintf(stderr, "Line:%s", line); + } + ia_store(&data_array, data_items, data); + data_items++; + } + fclose(in_file); +} +/******************************************************** + * print_histogram -- print the histogram output. * + ********************************************************/ +void print_histogram(void) +{ + /* upper bound for printout */ + int counters[NUMBER_OF_LINES]; + float low; /* lower bound for printout */ + int out_of_range = 0;/* number of items out of bounds */ + int max_count = 0;/* biggest counter */ + float scale; /* scale for outputting dots */ + int index; /* index into the data */ + + (void) memset((char *) counters, '\0', sizeof(counters)); + + for (index = 0; index < data_items; index++) { + float data;/* data for this point */ + + data = ia_get(&data_array, index); + + if ((data < LOW_BOUND) || (data > HIGH_BOUND)) + out_of_range++; + else { + /* index into counters array */ + int count_index; + + count_index = (data - LOW_BOUND) / FACTOR; + + counters[count_index]++; + if (counters[count_index] > max_count) + max_count = counters[count_index]; + } + } + + scale = ((float) max_count) / ((float) WIDTH); + + low = LOW_BOUND; + for (index = 0; index < NUMBER_OF_LINES; index++) { + /* index for outputting the dots */ + int char_index; + int number_of_dots; /* number of * to output */ + + (void) printf("%2d:%3.0f-%3.0f (%4d): ", + index, low, low + FACTOR -1, + counters[index]); + + number_of_dots = (int) (((float) counters[index]) / scale); + for (char_index = 0; char_index < number_of_dots; + char_index++) + (void) printf("*"); + (void) printf("\n"); + low += FACTOR; + } + (void) printf("%d items out of range\n", out_of_range); +} diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/HEADER.html b/reference/C/CONTRIB/OR_PRACTICAL_C/HEADER.html new file mode 100644 index 0000000..56e67da --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/HEADER.html @@ -0,0 +1,10 @@ +

Practical C - O'Reilly

+Reprinted with permission from +'Practical C Programming' copyright 1993 O'Reilly and Associates, Inc. For +orders and information, call 1-800-988-9938. +

+Source directory can be extracted from +ftp.uu.net:/published/oreilly/nutshell/practical_c. +

+I strongly recomended you get the book to put these examples into +context. Martin diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/Makefile.am b/reference/C/CONTRIB/OR_PRACTICAL_C/Makefile.am new file mode 100644 index 0000000..9bdc55f --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/Makefile.am @@ -0,0 +1,6 @@ +EXTRA_DIST = $(wildcard *.html) $(wildcard *.c) $(wildcard *.h) troff.test test.csh \ + makefile.tcc makefile.unix standard.mac +docs_DATA = $(EXTRA_DIST) + +docsdir = $(kde_htmldir)/en/kdevelop/$(subdir) + diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/Makefile.in b/reference/C/CONTRIB/OR_PRACTICAL_C/Makefile.in new file mode 100644 index 0000000..f547246 --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/Makefile.in @@ -0,0 +1,412 @@ +# KDE tags expanded automatically by am_edit - $Revision: 1.2 $ +# Makefile.in generated automatically by automake 1.5 from Makefile.am. + +# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +# Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = ../../../.. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_HEADER = $(INSTALL_DATA) +transform = @program_transform_name@ +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_alias = @build_alias@ +build_triplet = @build@ +host_alias = @host_alias@ +host_triplet = @host@ +target_alias = @target_alias@ +target_triplet = @target@ +AMTAR = @AMTAR@ +ARTSCCONFIG = @ARTSCCONFIG@ +AS = @AS@ +AUTODIRS = @AUTODIRS@ +AWK = @AWK@ +CC = @CC@ +CONF_FILES = @CONF_FILES@ +CPP = @CPP@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +DCOPIDL = @DCOPIDL@ +DCOPIDL2CPP = @DCOPIDL2CPP@ +DCOP_DEPENDENCIES = @DCOP_DEPENDENCIES@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DPMSINC = @DPMSINC@ +DPMSLIB = @DPMSLIB@ +EXEEXT = @EXEEXT@ +GCJ = @GCJ@ +GCJFLAGS = @GCJFLAGS@ +GLINC = @GLINC@ +GLLIB = @GLLIB@ +GMSGFMT = @GMSGFMT@ +IDL = @IDL@ +IDL_DEPENDENCIES = @IDL_DEPENDENCIES@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +JAR = @JAR@ +JAVAC = @JAVAC@ +JAVAH = @JAVAH@ +JVMLIBS = @JVMLIBS@ +KDECONFIG = @KDECONFIG@ +KDE_CXXFLAGS = @KDE_CXXFLAGS@ +KDE_EXTRA_RPATH = @KDE_EXTRA_RPATH@ +KDE_INCLUDES = @KDE_INCLUDES@ +KDE_LDFLAGS = @KDE_LDFLAGS@ +KDE_PLUGIN = @KDE_PLUGIN@ +KDE_RPATH = @KDE_RPATH@ +KDE_USE_CLOSURE_FALSE = @KDE_USE_CLOSURE_FALSE@ +KDE_USE_CLOSURE_TRUE = @KDE_USE_CLOSURE_TRUE@ +KDE_USE_FINAL_FALSE = @KDE_USE_FINAL_FALSE@ +KDE_USE_FINAL_TRUE = @KDE_USE_FINAL_TRUE@ +KDE_XSL_STYLESHEET = @KDE_XSL_STYLESHEET@ +LIBCOMPAT = @LIBCOMPAT@ +LIBCRYPT = @LIBCRYPT@ +LIBDL = @LIBDL@ +LIBGEN = @LIBGEN@ +LIBJPEG = @LIBJPEG@ +LIBMICO = @LIBMICO@ +LIBOBJS = @LIBOBJS@ +LIBPNG = @LIBPNG@ +LIBPTHREAD = @LIBPTHREAD@ +LIBPYTHON = @LIBPYTHON@ +LIBQIMGIO = @LIBQIMGIO@ +LIBRESOLV = @LIBRESOLV@ +LIBSHADOW = @LIBSHADOW@ +LIBSM = @LIBSM@ +LIBSOCKET = @LIBSOCKET@ +LIBTIFF = @LIBTIFF@ +LIBTOOL = @LIBTOOL@ +LIBUCB = @LIBUCB@ +LIBUTIL = @LIBUTIL@ +LIBXINERAMA = @LIBXINERAMA@ +LIBZ = @LIBZ@ +LIB_KAB = @LIB_KAB@ +LIB_KDECORE = @LIB_KDECORE@ +LIB_KDEUI = @LIB_KDEUI@ +LIB_KFILE = @LIB_KFILE@ +LIB_KFM = @LIB_KFM@ +LIB_KFORMULA = @LIB_KFORMULA@ +LIB_KHTML = @LIB_KHTML@ +LIB_KIMGIO = @LIB_KIMGIO@ +LIB_KIO = @LIB_KIO@ +LIB_KPARTS = @LIB_KPARTS@ +LIB_KSPELL = @LIB_KSPELL@ +LIB_KSYCOCA = @LIB_KSYCOCA@ +LIB_KWRITE = @LIB_KWRITE@ +LIB_QT = @LIB_QT@ +LIB_SMB = @LIB_SMB@ +LIB_X11 = @LIB_X11@ +LN_S = @LN_S@ +MCOPIDL = @MCOPIDL@ +MEINPROC = @MEINPROC@ +MICO_INCLUDES = @MICO_INCLUDES@ +MICO_LDFLAGS = @MICO_LDFLAGS@ +MOC = @MOC@ +MSGFMT = @MSGFMT@ +NOOPT_CXXFLAGS = @NOOPT_CXXFLAGS@ +NOREPO = @NOREPO@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PAMLIBS = @PAMLIBS@ +PASSWDLIBS = @PASSWDLIBS@ +PYTHONINC = @PYTHONINC@ +PYTHONLIB = @PYTHONLIB@ +PYTHONMODDIR = @PYTHONMODDIR@ +QT_INCLUDES = @QT_INCLUDES@ +QT_LDFLAGS = @QT_LDFLAGS@ +RANLIB = @RANLIB@ +REPO = @REPO@ +SETUIDFLAGS = @SETUIDFLAGS@ +STRIP = @STRIP@ +TOPSUBDIRS = @TOPSUBDIRS@ +UIC = @UIC@ +UIC_TR = @UIC_TR@ +USER_INCLUDES = @USER_INCLUDES@ +USER_LDFLAGS = @USER_LDFLAGS@ +USE_EXCEPTIONS = @USE_EXCEPTIONS@ +USE_RTTI = @USE_RTTI@ +USE_THREADS = @USE_THREADS@ +VERSION = @VERSION@ +XGETTEXT = @XGETTEXT@ +XPMINC = @XPMINC@ +XPMLIB = @XPMLIB@ +X_EXTRA_LIBS = @X_EXTRA_LIBS@ +X_INCLUDES = @X_INCLUDES@ +X_LDFLAGS = @X_LDFLAGS@ +X_PRE_LIBS = @X_PRE_LIBS@ +all_includes = @all_includes@ +all_libraries = @all_libraries@ +am__include = @am__include@ +am__quote = @am__quote@ +idldir = @idldir@ +install_sh = @install_sh@ +jni_includes = @jni_includes@ +kde_appsdir = @kde_appsdir@ +kde_bindir = @kde_bindir@ +kde_confdir = @kde_confdir@ +kde_datadir = @kde_datadir@ +kde_htmldir = @kde_htmldir@ +kde_icondir = @kde_icondir@ +kde_includes = @kde_includes@ +kde_libraries = @kde_libraries@ +kde_libs_htmldir = @kde_libs_htmldir@ +kde_libs_prefix = @kde_libs_prefix@ +kde_locale = @kde_locale@ +kde_mimedir = @kde_mimedir@ +kde_moduledir = @kde_moduledir@ +kde_qtver = @kde_qtver@ +kde_servicesdir = @kde_servicesdir@ +kde_servicetypesdir = @kde_servicetypesdir@ +kde_sounddir = @kde_sounddir@ +kde_templatesdir = @kde_templatesdir@ +kde_wallpaperdir = @kde_wallpaperdir@ +micodir = @micodir@ +qt_includes = @qt_includes@ +qt_libraries = @qt_libraries@ +x_includes = @x_includes@ +x_libraries = @x_libraries@ + +EXTRA_DIST = $(wildcard *.html) $(wildcard *.c) $(wildcard *.h) troff.test test.csh \ + makefile.tcc makefile.unix standard.mac + +docs_DATA = $(EXTRA_DIST) + +docsdir = $(kde_htmldir)/en/kdevelop/$(subdir) +subdir = reference/C/CONTRIB/OR_PRACTICAL_C +mkinstalldirs = $(SHELL) $(top_srcdir)/admin/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +DIST_SOURCES = +DATA = $(docs_DATA) + +DIST_COMMON = Makefile.am Makefile.in +#>- all: all-am +#>+ 1 +all: docs-am all-am + +.SUFFIXES: + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) +#>- cd $(top_srcdir) && \ +#>- $(AUTOMAKE) --gnu reference/C/CONTRIB/OR_PRACTICAL_C/Makefile +#>+ 3 + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu reference/C/CONTRIB/OR_PRACTICAL_C/Makefile + cd $(top_srcdir) && perl admin/am_edit reference/C/CONTRIB/OR_PRACTICAL_C/Makefile.in +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) && \ + CONFIG_HEADERS= CONFIG_LINKS= \ + CONFIG_FILES=$(subdir)/$@ $(SHELL) ./config.status +uninstall-info-am: +install-docsDATA: $(docs_DATA) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(docsdir) + @list='$(docs_DATA)'; for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + f="`echo $$p | sed -e 's|^.*/||'`"; \ + echo " $(INSTALL_DATA) $$d$$p $(DESTDIR)$(docsdir)/$$f"; \ + $(INSTALL_DATA) $$d$$p $(DESTDIR)$(docsdir)/$$f; \ + done + +uninstall-docsDATA: + @$(NORMAL_UNINSTALL) + @list='$(docs_DATA)'; for p in $$list; do \ + f="`echo $$p | sed -e 's|^.*/||'`"; \ + echo " rm -f $(DESTDIR)$(docsdir)/$$f"; \ + rm -f $(DESTDIR)$(docsdir)/$$f; \ + done +tags: TAGS +TAGS: + + +#>- DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +#>+ 4 +KDE_DIST=12_3.c 14_18.c 05_2.c 04_4.c 14_01.c 15_1.c 12_7.c 01_1.c 07_2.c 14_13.c 17_1.c 16_3.c 14_05.c 03_1.c 09_2.c 12_2.c 14_17.c 14_09.c 05_1.c 04_3.c 12_6.c tlint.c 07_1.c 06_3.c 14_12.c 10_1.c 04_7.c 16_2.c 14_04.c gen.h 09_1.c symbol.c 08_3.c font.h 12_1.c 14_16.c 14_08.c macro.h 04_2.c 03_4.c 09_5.c 12_5.c fonts.c 06_2.c 14_11.c 04_6.c 16_1.c 14_03.c 02_1.c 08_2.c 14_15.c 14_07.c 04_1.c 03_3.c 09_4.c 13_2.c 12_4.c 14_19.c HEADER.html macros.c 06_1.c 05_3.c 14_10.c 04_5.c 14_02.c 12_8.c 01_2.c 08_1.c 07_3.c 11_1.c 14_14.c 17_2.c 14_06.c 03_2.c 09_3.c 13_1.c + +DISTFILES= $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) $(KDE_DIST) + + +top_distdir = ../../../.. +distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + if test -f $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + $(mkinstalldirs) "$(distdir)/$$dir"; \ + fi; \ + if test -d $$d/$$file; then \ + cp -pR $$d/$$file $(distdir) \ + || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(DATA) + +installdirs: + $(mkinstalldirs) $(DESTDIR)$(docsdir) + +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) stamp-h stamp-h[0-9]* + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +#>- clean: clean-am +#>+ 1 +clean: kde-rpo-clean clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + +distclean-am: clean-am distclean-generic distclean-libtool + +dvi: dvi-am + +dvi-am: + +info: info-am + +info-am: + +install-data-am: install-docsDATA + +install-exec-am: + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +uninstall-am: uninstall-docsDATA uninstall-info-am + +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + distclean distclean-generic distclean-libtool distdir dvi \ + dvi-am info info-am install install-am install-data \ + install-data-am install-docsDATA install-exec install-exec-am \ + install-info install-info-am install-man install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool uninstall uninstall-am uninstall-docsDATA \ + uninstall-info-am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: + +#>+ 2 +docs-am: + +#>+ 6 +force-reedit: + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu reference/C/CONTRIB/OR_PRACTICAL_C/Makefile + cd $(top_srcdir) && perl admin/am_edit reference/C/CONTRIB/OR_PRACTICAL_C/Makefile.in + + +#>+ 2 +final: + $(MAKE) all-am +#>+ 2 +final-install: + $(MAKE) install-am +#>+ 2 +no-final: + $(MAKE) all-am +#>+ 2 +no-final-install: + $(MAKE) install-am +#>+ 3 +cvs-clean: + $(MAKE) -f $(top_srcdir)/admin/Makefile.common cvs-clean + +#>+ 3 +kde-rpo-clean: + -rm -f *.rpo diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/font.h b/reference/C/CONTRIB/OR_PRACTICAL_C/font.h new file mode 100644 index 0000000..46962dd --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/font.h @@ -0,0 +1,20 @@ +/******************************************************** + * font.h -- Definitions for the font package * + * package. * + * * + * Procedures * + * load_fonts -- load a font file onto the symbol * + * table * + ********************************************************/ + +extern struct symbol *font_symbol_ptr; /* A list of + legal fonts */ +/******************************************************** + * load_fonts -- load fonts into symbol table * + * * + * Parameters * + * file_name -- filename of file to load * + * * + * Aborts on error * + ********************************************************/ +void load_fonts(char *name); diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/fonts.c b/reference/C/CONTRIB/OR_PRACTICAL_C/fonts.c new file mode 100644 index 0000000..61f1496 --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/fonts.c @@ -0,0 +1,65 @@ +/******************************************************** + * fonts -- handle font-related data structures * + * * + * Functions * + * load_fonts -- load a font file * + ********************************************************/ +#include +#include "gen.h" +#include "symbol.h" +#include +#include + +/* the top of the symbol table */ +struct symbol *font_symbol_ptr = NULL; +/******************************************************** + * load_fonts -- load fonts into symbol table * + * * + * Parameters * + * file_name -- filename of file to load * + * * + * Aborts on error. * + ********************************************************/ +void load_fonts(char *file_name) +{ + FILE *in_file; /* Input file */ + char name[3]; /* Name of the current font */ + /* We have to point to something for our data */ + static char *an_object = "an object"; + + in_file = fopen(file_name, "r"); + if (in_file == NULL) { + (void) fprintf(stderr, "Error:Can't open %s for reading\n", file_name); + exit(8); + } + + while (1) { + char line[80]; /* Input line from data file */ + char *cur_char; /* Pointer to current input character */ + + if (fgets(line, sizeof(line), in_file) == NULL) { + (void) fclose(in_file); + return; + } + cur_char = line; + + while (*cur_char != '\0') { + SKIP_WHITESPACE(cur_char); + + if (*cur_char == '\0') + break; + + /* Copy two-character macro name */ + name[0] = *cur_char; + cur_char++; + if (*cur_char > ' ') { + name[1] = *cur_char; + cur_char++; + name[2] = '\0'; + } else + name[1] = '\0'; + + enter(&font_symbol_ptr, name, (generic *) an_object); + } + } +} diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/gen.h b/reference/C/CONTRIB/OR_PRACTICAL_C/gen.h new file mode 100644 index 0000000..b8f342a --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/gen.h @@ -0,0 +1,25 @@ +/******************************************************** + * gen.h -- general purpose macros. * + ********************************************************/ + +/* + * Define a boolean type + */ +#ifndef TRUE +typedef int boolean; +#define TRUE 1 +#define FALSE 0 +#endif /* TRUE */ + +/******************************************************** + * SKIP_WHITESPACE -- move a character pointer * + * past whitespace * + * * + * Parameters * + * cur_char -- pointer to current character * + * (will be moved) * + ********************************************************/ +/* Move past whitespace */ +#define SKIP_WHITESPACE(cur_char) \ + while ((*(cur_char) <= ' ') && (*(cur_char) != '\0')) \ + (cur_char)++; diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/macro.h b/reference/C/CONTRIB/OR_PRACTICAL_C/macro.h new file mode 100644 index 0000000..791eedd --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/macro.h @@ -0,0 +1,26 @@ +/******************************************************** + * macros.h -- Definitions for the macro lookup * + * package. * + * * + * Procedures * + * load_macros -- load a macro onto the symbol tbl * + * * + * macro_check -- check a macro line for * + * correctness * + ********************************************************/ + +/******************************************************** + * load_macros -- load macros into symbol table * + * * + * Parameters * + * name -- filename of file to load * + ********************************************************/ +void load_macros(char *name); + +/******************************************************** + * macro_check -- check a macro line for correctness * + * * + * Parameters * + * line -- line to check * + ********************************************************/ +void macro_check(char *name); diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/macros.c b/reference/C/CONTRIB/OR_PRACTICAL_C/macros.c new file mode 100644 index 0000000..ae5f221 --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/macros.c @@ -0,0 +1,418 @@ +/******************************************************** + * macros -- Handle macro related data structure. * + * * + * Functions * + * load_macros -- load a macro file into the macro * + * symbol table * + * macro_check -- check macro line * + ********************************************************/ +#include +#include "gen.h" +#include "symbol.h" +#include "macro.h" +#include "font.h" +#include +#include +#include +extern void error(char *); /* Write error message */ + +/* + * Each argument to a macro has the following structure + */ +struct arg { + char type; /* Type of argument */ + boolean many; /* True if we can repeat this argument */ +}; + +#define MAX_ARGS 10 /* Max arguments for each macro */ + +struct arg_list { + int num_args; /* Number of arguments */ + struct arg args[MAX_ARGS]; /* The arguments */ +}; + +/* the top of the symbol table */ +static struct symbol *macro_symbol_ptr = NULL; + +/* + * Skip past remaining argument + */ +#define SKIP_ARG(cur_char) \ + while (*(cur_char) > ' ') \ + (cur_char)++; + +/******************************************************** + * load_macros -- load macros into symbol table * + * * + * Parameters * + * name -- filename of file to load * + * * + * Aborts on error. * + *------------------------------------------------------* + * Input file format: * + * # line -- comment * + * mac arg arg # comment * + * * + * mac -- one or two-character macro name * + * arg -- argument type letter * + * | -- vertical bar * + * s -- string * + * n -- number * + * c -- single character * + * f -- font specification * + * t -- three-part title * + * * + * If followed by a star, set the many flag. * + ********************************************************/ +void load_macros(char *name) +{ + FILE *in_file; /* Input file */ + int line_number; /* Line number of the input file */ + char *type_list = "|sncft"; /* Characters for argument type */ + int num_args;/* Number of arguments we've seen */ + char macro_name[3]; /* Name of the current macro */ + + /* The macro we are working on */ + struct arg_list *arg_list_ptr; + + in_file = fopen(name, "r"); + if (in_file == NULL) { + (void) fprintf(stderr, "Error:Can't open %s for reading\n", name); + exit(8); + } + line_number = 0; + + while (1) { + char line[80]; /* Input line from data file */ + char *cur_char; /* Pointer to current input character */ + + if (fgets(line, sizeof(line), in_file) == NULL) { + (void) fclose(in_file); + return; + } + line_number++; + + cur_char = line; + /* Trim off leading whitespace */ + SKIP_WHITESPACE(cur_char); + + /* Continue on comment or blank line */ + if ((*cur_char == '#') || (cur_char == '\0')) + continue; + + /* Copy two-character macro name */ + macro_name[0] = *cur_char; + cur_char++; + if (*cur_char > ' ') { + macro_name[1] = *cur_char; + cur_char++; + macro_name[2] = '\0'; + } else + macro_name[1] = '\0'; + + /* + * create new argument list + */ + arg_list_ptr = (struct arg_list *) malloc(sizeof(struct arg_list)); + + for (num_args = 0; num_args < MAX_ARGS; num_args++) { + + /* Move past whitespace */ + SKIP_WHITESPACE(cur_char); + + /* End of list? */ + if ((*cur_char == '#') || (cur_char == '\0')) + break; + + /* Check for legal character */ + if (strchr(type_list, *cur_char) == NULL) { + (void) fprintf(stderr, + "Error on line %d:Bad argument character %c\n", + line_number, *cur_char); + } + arg_list_ptr->args[num_args].type = *cur_char; + cur_char++; + + if (*cur_char == '*') { + arg_list_ptr->args[num_args].many = TRUE; + cur_char++; + } else + arg_list_ptr->args[num_args].many = FALSE; + + } + arg_list_ptr->num_args = num_args; + enter(¯o_symbol_ptr, macro_name, (generic *) arg_list_ptr); + } +} +/******************************************************** + * macro_check -- check a macro line for correctness * + * * + * Parameters * + * line -- line to check * + ********************************************************/ +void macro_check(char *line) +{ + char *cur_char = &line[1]; /* Pointer to current character */ + char name[3]; /* Macro name */ + struct arg_list *arg_list_ptr; /* The argument list */ + int arg_index; /* Index into argument list */ + + extern char *check_string(char *); /* String? */ + extern char *check_number(char *); /* Number? */ + extern char *check_char(char *); /* Character? */ + extern char *check_font(char *); /* Font specification? */ + extern char *check_title(char *); /* Three-part title? */ + + SKIP_WHITESPACE(cur_char); + + /* Copy two-character macro name */ + name[0] = *cur_char; + cur_char++; + if (*cur_char > ' ') { + name[1] = *cur_char; + cur_char++; + name[2] = '\0'; + } else + name[1] = '\0'; + + arg_list_ptr = (struct arg_list *) lookup(macro_symbol_ptr, name); + + if (arg_list_ptr == NULL) { + char error_msg[30]; + (void) sprintf(error_msg, "No such macro %s", name); + error(error_msg); + return; + } + arg_index = 0; + while (1) { + if (arg_index >= arg_list_ptr->num_args) + break; + + /* Start at beginning of next macro */ + SKIP_WHITESPACE(cur_char); + + /* Check for end of string */ + if (*cur_char == '\0') + break; + + switch (arg_list_ptr->args[arg_index].type) { + /* Vertical Bar (optional) */ + case '|': + if (*cur_char == '|') + cur_char++; + break; + + /* s -- a string */ + case 's': + cur_char = check_string(cur_char); + break; + + /* n -- number */ + case 'n': + cur_char = check_number(cur_char); + break; + + /* c -- character */ + case 'c': + cur_char = check_char(cur_char); + break; + + /* f -- font specification */ + case 'f': + cur_char = check_font(cur_char); + break; + + /* t -- three-part title */ + case 't': + cur_char = check_title(cur_char); + break; + + default: + (void) printf("Internal error, bad type %c\n", + arg_list_ptr->args[arg_index].type); + break; + } + + if (arg_list_ptr->args[arg_index].many == FALSE) + arg_index++; + + } + SKIP_WHITESPACE(cur_char); + if (*cur_char != '\0') + error("Too many arguments"); +} +/******************************************************** + * check_string -- check argument to make sure it's * + * pointing to a string * + * * + * A string is a word or a set of words enclosed in * + * double quotes. * + * * + * I.E. sam "This is a test" * + * * + * Parameters * + * cur_char -- pointer to the string * + * * + * Returns * + * pointer to character after the string * + ********************************************************/ +char *check_string(char *cur_char) +{ + /* What type of string is it? */ + + /* Quoted string? */ + if (*cur_char == '"') { + cur_char++; + + /* Move to end of string */ + while ((*cur_char != '"') && (*cur_char != '\0')) + cur_char++; + + /* Check for proper termination */ + if (*cur_char == '\0') + error("Missing closing \" on string parameter"); + else + cur_char++; /* Move past closing quote */ + + } else { + /* Simple word string */ + while (!isspace(*cur_char)) + cur_char++; + } + return (cur_char); +} +/******************************************************** + * check_number -- check argument to make sure it's * + * pointing to a expression * + * * + * Parameters * + * cur_char -- pointer to the integer expression * + * * + * * + * Returns * + * pointer to character after the integer exp * + ********************************************************/ +char *check_number(char *cur_char) +{ + /* Characters allowed in expressions */ + static char *number_chars = "0123456789+-*/%."; + + if (strchr(number_chars, *cur_char) == NULL) { + error("Expression expected"); + SKIP_ARG(cur_char); + return (cur_char); + } + while (strchr(number_chars, *cur_char) != NULL) + cur_char++; + + if (!(isspace(*cur_char) || (*cur_char == '\0'))) { + SKIP_ARG(cur_char); + error("Illegal expression"); + } + + return (cur_char); +} +/******************************************************** + * check_char -- check argument to make sure it's * + * pointing to a char * + * * + * Parameters * + * cur_char -- pointer to the char * + * * + * Returns * + * pointer to character after the char * + * * + * Note: This is a simple character check and does not * + * try to figure out all of the crazy \ * + * characters that can be used in troff. * + ********************************************************/ +char *check_char(char *cur_char) +{ + cur_char++; + + if (!(isspace(*cur_char) || (*cur_char == '\0'))) + error("Expected single character"); + + return (cur_char); +} +/******************************************************** + * check_font -- check argument to make sure it's * + * pointing to a legal font * + * * + * Parameters * + * cur_char -- pointer to the font * + * * + * Returns * + * pointer to character after the font * + ********************************************************/ +char *check_font(char *cur_char) +{ + char name[3]; /* Font name */ + + name[0] = *cur_char; + cur_char++; + + if (isalnum(*cur_char)) { + name[1] = *cur_char; + cur_char++; + name[2] = '\0'; + } else + name[1] = '\0'; + + if (lookup(font_symbol_ptr, name) == NULL) + error("Expected font"); + + return (cur_char); +} + +/******************************************************** + * check_title -- check argument to make sure it's * + * pointing to a three-part title * + * of the form: 'xxxx'yyyy'zzz'. * + * * + * Parameters * + * cur_char -- pointer to the title * + * * + * Returns * + * pointer to character after the title * + ********************************************************/ +char *check_title(char *cur_char) +{ + if (*cur_char != '\'') { + error("Expected beginning of three-part title"); + SKIP_ARG(cur_char); + return (cur_char); + } + cur_char++; + + while ((*cur_char != '\'') && (*cur_char != '\0')) + cur_char++; + + if (*cur_char != '\'') { + error("Expected middle part of three-part title"); + SKIP_ARG(cur_char); + return (cur_char); + } + cur_char++; + + while ((*cur_char != '\'') && (*cur_char != '\0')) + cur_char++; + + if (*cur_char != '\'') { + error("Expected third part of three-part title"); + SKIP_ARG(cur_char); + return (cur_char); + } + cur_char++; + + while ((*cur_char != '\'') && (*cur_char != '\0')) + cur_char++; + + if (*cur_char != '\'') { + error("Expected end of three-part title"); + SKIP_ARG(cur_char); + return (cur_char); + } + cur_char++; + return (cur_char); +} diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/makefile.tcc b/reference/C/CONTRIB/OR_PRACTICAL_C/makefile.tcc new file mode 100644 index 0000000..e96bd90 --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/makefile.tcc @@ -0,0 +1,19 @@ +CC=tcc +CFLAGS=-ml -g -w -A +SRCS=tlint.c macros.c symbol.c fonts.c +OBJS=tlint.obj macros.obj symbol.obj fonts.obj + +tlint: $(OBJS) + $(CC) $(CFLAGS) -etlint $(OBJS) + +fonts.obj: fonts.c gen.h symbol.h + $(CC) $(CFLAGS) -c fonts.c + +macros.obj: font.h gen.h macro.h macros.c symbol.h + $(CC) $(CFLAGS) -c macros.c + +symbol.obj: symbol.c symbol.h + $(CC) $(CFLAGS) -c symbol.c + +tlint.obj: font.h gen.h macro.h tlint.c + $(CC) $(CFLAGS) -c tlint.c diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/makefile.unix b/reference/C/CONTRIB/OR_PRACTICAL_C/makefile.unix new file mode 100644 index 0000000..292313f --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/makefile.unix @@ -0,0 +1,16 @@ +SRCS=tlint.c macros.c symbol.c fonts.c +OBJS=tlint.o macros.o symbol.o fonts.o + +tlint:$(OBJS) + cc $(CFLAGS) -o tlint $(OBJS) + +lint: + lint -xh $(SRCS) + +fonts.o: fonts.c gen.h symbol.h + +macros.o: font.h gen.h macro.h macros.c symbol.h + +symbol.o: symbol.c symbol.h + +tlint.o: font.h gen.h macro.h tlint.c diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/standard.mac b/reference/C/CONTRIB/OR_PRACTICAL_C/standard.mac new file mode 100644 index 0000000..07aa74f --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/standard.mac @@ -0,0 +1,100 @@ +# +# This file contains the definitions for the built-in +# macros used by troff +# +# The format of the file is +# macro +# +# Arguments are: +# | Vertical bar +# s String +# n Numeric expression +# c Single character +# f Font specification +# t Three-part title +# +# If followed by a * they can be repeated 0 or more +# times +# +# Anything past a # is considered a comment +br # Break +ad s # Adjust margins +na # No adjust +nf # No fill +fi # Fill +nh # No hyphen +hy n # Set hyphenation mode +hw s* # Specify how to hyphenate words +hc c # Hyphenation character +ce n # Center lines +ul n # Underline +cu n # Continuous underline +uf f # Select font for underline +po | n # Page offset +ll n # Line length +in | n # Indent +ti | n # Temporary indent +pl | n # Page length +bp n # Begin page +pn n # Page number +ne n # Specify need space +mk s # Mark current location +sp | n # Vertical space +ps n # Point size +vs | n # Vertical space +ls n # Line spacing +sv n # Save space +os # Output saved space +ns # Set no-space mode +rs # Set restore-space mode +ss n # Set character space size +cs s n n # Constant space mode +ft f # Specify font +fp f n # Set font position +fz f n # Font size request +bd f n # Specify how to bold a font +lg n # Select ligatures +ta n* # Specify tabs +tc c # Tab character +lc c # Leader character +fc c s # Field character +lt | n # Title length +pc c # Page character +tl t # Title +so s # Source another file +nx s # Change to another file +pi s # Pipe output to a program +rd s # Read data from keyboard +ex s # Exit +tm s* # Send message to standard output +ds s s # Define string +as s s # Append string +de s s # Define macro +. # End of macro +rm s # Remove macro +rn s s # Rename macro +am s s # Append to macro +di s # Divert to macro +da s # Append to diversion +wh n s # Set place to execute macro +ch s n # Change place macro executes +dt n s # Set diversion trap +it n s # Set input trap +em s # Set macro for end of input +nr s n n # Define number register +af s c # Assign format +rr s # Remove register +mc c # Margin character +ec c # Set escape character +eo # Turn off escape +cc c # Set control character +c2 # Set second control character +tr s # Translate characters +nm n n n n # Line number +nn n # No numbering +ig s # Ignore input +pm s # Print macros +fl # Flush output +ab s # Abort +ev n # Set environment +\" s* # Comment diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/symbol.c b/reference/C/CONTRIB/OR_PRACTICAL_C/symbol.c new file mode 100644 index 0000000..600bc4c --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/symbol.c @@ -0,0 +1,77 @@ +/******************************************************** + * symbol -- handle the symbol table * + * * + * Functions * + * enter -- put a symbol in a symbol table * + * lookup -- get the data associated with a symbol * + ********************************************************/ +#include +#include "symbol.h" +#include +#include + +/******************************************************** + * enter -- enter a word into the symbol table * + * * + * Parameters * + * node -- top node of the symbol table for add * + * symbol -- symbol name to add (1 or 2 chars) * + * data -- data associated with the symbol * + ********************************************************/ +void enter(struct symbol **node_ptr, char *symbol, generic *data) +{ + int result; /* result of strcmp */ + /* New node that we are creating */ + struct symbol *new_node_ptr; + + /* see if we have reached the end */ + if ((*node_ptr) == NULL) { + new_node_ptr = (struct symbol *) malloc(sizeof(struct symbol)); + (void)strcpy(new_node_ptr->name, symbol); + new_node_ptr->data = data; + new_node_ptr->left_ptr = NULL; + new_node_ptr->right_ptr = NULL; + *node_ptr = new_node_ptr; + return; + } + /* + * Need to sub-divide the symbol table and try again + */ + result = strcmp((*node_ptr)->name, symbol); + + if (result == 0) + return; + + if (result > 0) + enter(&(*node_ptr)->left_ptr, symbol, data); + else + enter(&(*node_ptr)->right_ptr, symbol, data); +} +/******************************************************** + * lookup -- lookup a symbol in a table * + * * + * Parameters * + * root -- root of the symbol table to search * + * name -- name to lookup. * + * * + * Returns * + * Pointer to the data or NULL if not found. * + ********************************************************/ +generic *lookup(struct symbol *root_ptr, char *name) +{ + int result; /* Result of string compare */ + + if (root_ptr == NULL) + return (NULL); + + result = strcmp(root_ptr->name, name); + + if (result == 0) { + return (root_ptr->data); + } + + if (result > 0) + return (lookup(root_ptr->left_ptr, name)); + else + return (lookup(root_ptr->right_ptr, name)); +} diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/test.csh b/reference/C/CONTRIB/OR_PRACTICAL_C/test.csh new file mode 100644 index 0000000..b3beec8 --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/test.csh @@ -0,0 +1,32 @@ +#!/bin/csh +# +# Test file for the program tlint +# +#---------------------------------------- +# Print commands as they are executed +# +set echo +#---------------------------------------- +# Try something normal +# +tlint troff.test +#---------------------------------------- +# Try non-existent macro and font file +tlint -mno-name +tlint -fno-name +#---------------------------------------- +# Try a bad macro file +tlint -mbad.mac Add the data from * + * to the tables used for syntax * + * checking. * + * -f Add font data from * + * to list of legal fonts. * + * * + * [files] is a list of files to check. * + * (none=check standard in.) * + * * + ********************************************************/ +#include +#include "gen.h" +#include "macro.h" +#include "font.h" +#include + +#define MAX_LINE 100 /* longest line we can expect */ + +#define MACRO_START_1 '.' /* Macros can begin with a dot */ +#define MACRO_START_2 '\'' /* or an apostrophe */ + +main(int argc, char *argv[]) +{ + void usage(void); /* Tell the user what to do */ + void do_file(char *, FILE *); /* Process a file */ + + load_macros("standard.mac"); + load_fonts("standard.fonts"); + + while ((argc > 1) && (argv[1][0] == '-')) { + switch (argv[1][1]) { + case 'm': + load_macros(&argv[1][2]); + break; + case 'f': + load_fonts(&argv[1][2]); + break; + default: + usage(); + } + argc--; + argv++; + } + if (argc == 1) { + do_file("standard-in", stdin); + } else { + while (argc > 1) { + FILE *in_file; /* File for reading data */ + + in_file = fopen(argv[1], "r"); + if (in_file == NULL) { + (void)fprintf(stderr,"Unable to open %s\n", argv[1]); + } else { + do_file(argv[1], in_file); + (void)fclose(in_file); + } + argc--; + argv++; + } + } + return (0); +} +/******************************************************** + * usage -- tell the user what to do * + ********************************************************/ +static void usage(void) +{ + (void)printf("Usage is:\n"); + (void)printf(" tlint [options] [file1] [file2] ...\n"); + (void)printf("Options:\n"); + (void)printf(" -m -- add to list\n"); + (void)printf(" of macro files\n"); + (void)printf(" -f -- specify additional font file\n"); + exit (8); +} +static char *file_name; /* Name of the file we are processing */ +static int line_number; /* Current line number */ +static char line[MAX_LINE]; /* A line from the input file */ +static int line_out; /* True if a line has been output */ +/******************************************************** + * do_file -- process a single file * + * * + * Parameters * + * name -- name of the file to use * + * in_file -- file to check * + ********************************************************/ +static void do_file(char *name, FILE *in_file) +{ + + file_name = name; + line_number = 0; + while (1) { + if (fgets(line, sizeof(line), in_file) == NULL) + break; + line_out = 0; /* We have not written the line */ + line_number++; + + if ((line[0] == MACRO_START_1) || (line[0] == MACRO_START_2)) + macro_check(line); + } +} +/******************************************************** + * error -- tell the user that there is an error * + * * + * Parameters * + * message -- error message * + ********************************************************/ +void error(char *message) +{ + if (line_out == 0) { + (void)fprintf(stderr,"%s", line); + line_out = 1; + } + (void)fprintf(stderr,"Error %s in file %s Line %d\n", + message, file_name, line_number); +} diff --git a/reference/C/CONTRIB/OR_PRACTICAL_C/troff.test b/reference/C/CONTRIB/OR_PRACTICAL_C/troff.test new file mode 100644 index 0000000..98686f7 --- /dev/null +++ b/reference/C/CONTRIB/OR_PRACTICAL_C/troff.test @@ -0,0 +1,36 @@ +Test file for the troff line program +.tm this is a test + .tm test is more test +.tm test once again +.xx this is an error +Test of macro that has no arguments +.br +Put an argument where there should be none +.br +Expect string argument +.tm string +Two strings +.tm string string +Integer +.br +12+34 +String where number expected +.br +test +Vertical bar +.lt |0 +No vertical bar +.lt 0 +Font check +Bad font check +Character +'left'middle'right' +bad +'bad +'bad'bad +'bad'bad' +"quoted string" +"almost quoted string +.sp 12.0 +Cause an expression error +.sp 12.0_12.0 diff --git a/reference/C/CONTRIB/OR_USING_C/02.1.c b/reference/C/CONTRIB/OR_USING_C/02.1.c new file mode 100644 index 0000000..bade646 --- /dev/null +++ b/reference/C/CONTRIB/OR_USING_C/02.1.c @@ -0,0 +1,49 @@ + +#include + +main(argc, argv) +int argc; +char **argv; +{ + int c; + FILE *from, *to; + + /* + * Check our arguments. + */ + if (argc != 3) { + fprintf(stderr, "Usage: %s from-file to-file\n", *argv); + exit(1); + } + + /* + * Open the from-file for reading. + */ + if ((from = fopen(argv[1], "r")) == NULL) { + perror(argv[1]); + exit(1); + } + + /* + * Open the to-file for appending. If to-file does + * not exist, fopen will create it. + */ + if ((to = fopen(argv[2], "a")) == NULL) { + perror(argv[2]); + exit(1); + } + + /* + * Now read characters from from-file until we + * hit end-of-file, and put them onto to-file. + */ + while ((c = getc(from)) != EOF) + putc(c, to); + + /* + * Now close the files. + */ + fclose(from); + fclose(to); + exit(0); +} diff --git a/reference/C/CONTRIB/OR_USING_C/02.2.c b/reference/C/CONTRIB/OR_USING_C/02.2.c new file mode 100644 index 0000000..7ea5ffd --- /dev/null +++ b/reference/C/CONTRIB/OR_USING_C/02.2.c @@ -0,0 +1,44 @@ +#include + +main(argc, argv) +int argc; +char **argv; +{ + FILE *from, *to; + char line[BUFSIZ]; + /* + * Check our arguments. + */ + if (argc != 3) { + fprintf(stderr, "Usage: %s from-file to-file\n", *argv); + exit(1); + } + /* + * Open the from-file for reading. + */ + if ((from = fopen(argv[1], "r")) == NULL) { + perror(argv[1]); + exit(1); + } + /* + * Open the to-file for appending. If to-file does + * not exist, fopen will create it. + */ + if ((to = fopen(argv[2], "a")) == NULL) { + perror(argv[2]); + exit(1); + } + /* + * Now read a line at a time from the from-file, + * and write it to the to-file. + */ + while (fgets(line, BUFSIZ, from) != NULL) + fputs(line, to); + /* + * Now close the files. + */ + fclose(from); + fclose(to); + exit(0); +} + diff --git a/reference/C/CONTRIB/OR_USING_C/02.3.c b/reference/C/CONTRIB/OR_USING_C/02.3.c new file mode 100644 index 0000000..e669d00 --- /dev/null +++ b/reference/C/CONTRIB/OR_USING_C/02.3.c @@ -0,0 +1,50 @@ +#include + +main(argc, argv) +int argc; +char **argv; +{ + int n; + FILE *from, *to; + char buf[BUFSIZ]; + + /* + * Check our arguments. + */ + if (argc != 3) { + fprintf(stderr, "Usage: %s from-file to-file\n", *argv); + exit(1); + } + + /* + * Open the from-file for reading. + */ + if ((from = fopen(argv[1], "r")) == NULL) { + perror(argv[1]); + exit(1); + } + + /* + * Open the to-file for appending. If to-file does + * not exist, fopen will create it. + */ + if ((to = fopen(argv[2], "a")) == NULL) { + perror(argv[2]); + exit(1); + } + + /* + * Note that we only write the number of characters fread + * read in, rather than always writing BUFSIZ characters. + */ + while ((n = fread(buf, sizeof(char), BUFSIZ, from)) > 0) + fwrite(buf, sizeof(char), n, to); + + /* + * Now close the files. + */ + fclose(from); + fclose(to); + exit(0); +} + diff --git a/reference/C/CONTRIB/OR_USING_C/02.4.c b/reference/C/CONTRIB/OR_USING_C/02.4.c new file mode 100644 index 0000000..4f2dd28 --- /dev/null +++ b/reference/C/CONTRIB/OR_USING_C/02.4.c @@ -0,0 +1,23 @@ +#include + +main() +{ + int n, m; + + printf("Enter a number: "); + scanf("%d", &n); + + m = fact(n); + printf("The factorial of %d is %d.\n", n, m); + exit(0); +} + +fact(n) +int n; +{ + if (n == 0) + return(1); + + return(n * fact(n-1)); +} + diff --git a/reference/C/CONTRIB/OR_USING_C/02.5.c b/reference/C/CONTRIB/OR_USING_C/02.5.c new file mode 100644 index 0000000..2b40798 --- /dev/null +++ b/reference/C/CONTRIB/OR_USING_C/02.5.c @@ -0,0 +1,69 @@ +/* + * + */ +#include + +struct record { + int uid; + char login[9]; +}; + +char *logins[] = { "user1", "user2", "user3", + "user4", "user5" }; + +main() +{ + int i; + FILE *fp; + struct record rec; + + /* + * Open the data file for writing. + */ + if ((fp = fopen("datafile", "w")) == NULL) { + perror("datafile"); + exit(1); + } + + /* + * For each user, going backwards... + */ + for (i = 4; i >= 0; i--) { + /* + * Create the record. + */ + rec.uid = i; + strcpy(rec.login, logins[i]); + + /* + * Output the record. Notice we pass the + * address of the structure. + */ + putrec(fp, i, &rec); + } + + fclose(fp); + exit(0); +} + +/* + * putrec--write the record in the i'th position. + */ +putrec(fp, i, r) +int i; +FILE *fp; +struct record *r; +{ + /* + * Seek to the i'th position from the beginning + * of the file. + */ + fseek(fp, (long) i * sizeof(struct record), 0); + + /* + * Write the record. We want to write one + * object the size of a record structure. + */ + fwrite(r, sizeof(struct record), 1, fp); +} + diff --git a/reference/C/CONTRIB/OR_USING_C/03.1.c b/reference/C/CONTRIB/OR_USING_C/03.1.c new file mode 100644 index 0000000..f1b7844 --- /dev/null +++ b/reference/C/CONTRIB/OR_USING_C/03.1.c @@ -0,0 +1,60 @@ +/* Change to if you're on System V. + */ +#include + +main(argc, argv) +int argc; +char **argv; +{ + int n; + int from, to; + char buf[1024]; + + /* + * Check our arguments. Note that to write the error + * message we can't just use "%s" as we did in Example + * 2-3; we have to write each string separately. + */ + if (argc != 3) { + write(2, "Usage: ", 7); + write(2, *argv, strlen(*argv)); + write(2, " from-file to-file\n", 19); + exit(1); + } + + /* + * Open the from-file for reading. + */ + if ((from = open(argv[1], O_RDONLY)) < 0) { + perror(argv[1]); + exit(1); + } + + /* + * Open the to-file for appending. If to-file does + * not exist, open will create it with mode 644 + * (-rw-r--r--). Note that we specify the mode + * in octal, not decimal + */ + if ((to = open(argv[2], O_WRONLY|O_CREAT|O_APPEND, 0644)) < 0) { + perror(argv[2]); + exit(1); + } + + /* + * Now read a buffer-full at a time from the from-file, + * and write it to the to-file. Note that we only + * write the number of characters read read in, + * rather than always writing 1024 characters. + */ + while ((n = read(from, buf, sizeof(buf))) > 0) + write(to, buf, n); + + /* + * Now close the files. + */ + close(from); + close(to); + exit(0); +} + diff --git a/reference/C/CONTRIB/OR_USING_C/03.2.c b/reference/C/CONTRIB/OR_USING_C/03.2.c new file mode 100644 index 0000000..69d8904 --- /dev/null +++ b/reference/C/CONTRIB/OR_USING_C/03.2.c @@ -0,0 +1,67 @@ +/* + * If you're on System V, change to . + */ +#include + +struct record { + int uid; + char login[9]; +}; + +char *logins[] = { "user1", "user2", "user3", + "user4", "user5" }; + +main() +{ + int i, fd; + struct record rec; + + /* + * Open the data file for writing. + */ + if ((fd = open("datafile", O_WRONLY | O_CREAT, 0644)) < 0) { + perror("datafile"); + exit(1); + } + + /* + * For each user, going backwards... + */ + for (i = 4; i >= 0; i--) { + /* + * Create the record. + */ + rec.uid = i; + strcpy(rec.login, logins[i]); + + /* + * Output the record. Notice we pass the + * address of the structure. + */ + putrec(fd, i, &rec); + } + + close(fd); + exit(0); +} + +/* + * putrec--write the record in the i'th position. + */ +putrec(fd, i, r) +int i, fd; +struct record *r; +{ + /* + * Seek to the i'th position from the beginning + * of the file. + */ + lseek(fd, (long) i * sizeof(struct record), L_SET); + + /* + * Write the record. We want to write one + * object the size of a record structure. + */ + write(fd, r, sizeof(struct record)); +} + diff --git a/reference/C/CONTRIB/OR_USING_C/04.1.c b/reference/C/CONTRIB/OR_USING_C/04.1.c new file mode 100644 index 0000000..bd0db3d --- /dev/null +++ b/reference/C/CONTRIB/OR_USING_C/04.1.c @@ -0,0 +1,44 @@ +/* + * Non-BSD systems only. + */ +#include +#include +#include + +main() +{ + FILE *fp; + struct direct dir; + int n; + + if ((fp = fopen(".", "r")) == NULL) { + perror("current directory"); + exit(1); + } + + /* + * Read directory entries. Since we're reading + * entries one at a time, we use the fread routine, + * which buffers them internally. Don't use the + * low-level read to do things this way, since + * reading very small quantities of data (16 bytes) + * at a time is very inefficient. + */ + while ((n = fread(&dir, sizeof(dir), 1, fp)) > 0) { + /* + * Skip removed files. + */ + if (dir.d_ino == 0) + continue; + + /* + * Make sure we print no more than DIRSIZ + * characters. + */ + printf("%.*s\n", DIRSIZ, dir.d_name); + } + + fclose(fp); + exit(0); +} + diff --git a/reference/C/CONTRIB/OR_USING_C/04.2.c b/reference/C/CONTRIB/OR_USING_C/04.2.c new file mode 100644 index 0000000..2f2cde2 --- /dev/null +++ b/reference/C/CONTRIB/OR_USING_C/04.2.c @@ -0,0 +1,34 @@ +/* + * For use with 4.2 and 4.3BSD systems. + */ +#include +#include +#include + +main() +{ + DIR *dp; + struct direct *dir; + + if ((dp = opendir(".")) == NULL) { + fprintf(stderr, "cannot open directory.\n"); + exit(1); + } + + /* + * Read entries... + */ + while ((dir = readdir(dp)) != NULL) { + /* + * Skip removed files. + */ + if (dir->d_ino == 0) + continue; + + printf("%s\n", dir->d_name); + } + + closedir(dp); + exit(0); +} + diff --git a/reference/C/CONTRIB/OR_USING_C/04.3.c b/reference/C/CONTRIB/OR_USING_C/04.3.c new file mode 100644 index 0000000..9c55974 --- /dev/null +++ b/reference/C/CONTRIB/OR_USING_C/04.3.c @@ -0,0 +1,183 @@ +#include +#include +#include +#include + +char *modes[] = { + "---", "--x", "-w-", "-wx", + "r--", "r-x", "rw-", "rwx" +}; + +main(argc, argv) +int argc; +char **argv; +{ + struct stat sbuf; + + /* + * If no arguments, list current directory. + */ + if (argc < 2) { + list("."); + exit(0); + } + + /* + * Process arguments. + */ + while (--argc) { + /* + * See what the file is. + */ + if (stat(*++argv, &sbuf) < 0) { + perror(*argv); + continue; + } + + /* + * If it's a directory we list it, + * otherwise just print the info about + * the file. + */ + if ((sbuf.st_mode & S_IFMT) == S_IFDIR) + list(*argv); + else + printout(".", *argv); + } + + exit(0); +} + +/* + * list--read a directory and list the files it + * contains. + */ +list(name) +char *name; +{ + DIR *dp; + struct direct *dir; + + /* + * Open the directory. + */ + if ((dp = opendir(name)) == NULL) { + fprintf(stderr, "%s: cannot open.\n", name); + return; + } + + /* + * For each entry... + */ + while ((dir = readdir(dp)) != NULL) { + /* + * Skip removed files. + */ + if (dir->d_ino == 0) + continue; + + /* + * Print it out. + */ + printout(name, dir->d_name); + } + + closedir(dp); +} + +/* + * printout--print out the information about + * a file. + */ +printout(dir, name) +char *dir, *name; +{ + int i, j; + char perms[10]; + struct stat sbuf; + char newname[1024]; + + /* + * Make full path name, so + * we have a legal path. + */ + sprintf(newname, "%s/%s", dir, name); + + /* + * At this point we know the file exists, + * so this won't fail. + */ + stat(newname, &sbuf); + + /* + * Print size in kbytes. + */ + printf("%5d ", (sbuf.st_size + 1023) / 1024); + + /* + * Get the file type. For convenience (and to + * make this example universal), we ignore the + * other types which are version-dependent. + */ + switch (sbuf.st_mode & S_IFMT) { + case S_IFREG: putchar('-'); break; + case S_IFDIR: putchar('d'); break; + case S_IFCHR: putchar('c'); break; + case S_IFBLK: putchar('b'); break; + default: putchar('?'); break; + } + + /* + * Get each of the three groups of permissions + * (owner, group, world). Since they're just + * bits, we can count in binary and use this + * as a subscript (see the modes array, above). + */ + *perms = NULL; + for (i = 2; i >= 0; i--) { + /* + * Since we're subscripting, we don't + * need the constants. Just get a + * value between 0 and 7. + */ + j = (sbuf.st_mode >> (i*3)) & 07; + + /* + * Get the perm bits. + */ + strcat(perms, modes[j]); + } + + /* + * Handle special bits which replace the 'x' + * in places. + */ + if ((sbuf.st_mode & S_ISUID) != 0) + perms[2] = 's'; + if ((sbuf.st_mode & S_ISGID) != 0) + perms[5] = 's'; + if ((sbuf.st_mode & S_ISVTX) != 0) + perms[8] = 't'; + + /* + * Print permissions, number of links, + * user and group ids. + */ + printf("%s%3d %5d/%-5d ", perms, sbuf.st_nlink, sbuf.st_uid, + sbuf.st_gid); + + /* + * Print the size of the file in bytes, + * and the last modification time. The + * ctime routine converts a time to ASCII; + * it is described in Chapter 7, Telling + * Time and Timing Things. + */ + printf("%7d %.12s ", sbuf.st_size, ctime(&sbuf.st_mtime)+4); + + /* + * Finally, print the filename. + */ + printf("%s\n", name); +} + diff --git a/reference/C/CONTRIB/OR_USING_C/05.1.c b/reference/C/CONTRIB/OR_USING_C/05.1.c new file mode 100644 index 0000000..7438fdc --- /dev/null +++ b/reference/C/CONTRIB/OR_USING_C/05.1.c @@ -0,0 +1,102 @@ +#include +#include + +main(argc, argv) +int argc; +char **argv; +{ + struct sgttyb sgo, sgn; + struct tchars tco, tcn; + + if (argc < 2) { + fprintf(stderr, "Usage: %s file [file ...]\n", *argv); + exit(1); + } + + /* + * In real life we'd check the return values of + * these, since if the input is redirected from + * a file they will fail. We are assuming the + * terminal is always connected to the standard + * input. + */ + ioctl(0, TIOCGETP, &sgo); + ioctl(0, TIOCGETC, &tco); + + sgn = sgo; + sgn.sg_flags &= ~ECHO; /* turn off ECHO */ + sgn.sg_flags |= CBREAK; /* turn on CBREAK */ + + tcn = tco; + tcn.t_intrc = -1; /* disable int key */ + + /* + * Set the new modes. Again we ignore return + * values. + */ + ioctl(0, TIOCSETP, &sgn); + ioctl(0, TIOCSETC, &tcn); + + while (--argc) + more(*++argv); + + /* + * Reset the old tty modes. + */ + ioctl(0, TIOCSETP, &sgo); + ioctl(0, TIOCSETC, &tco); + + exit(0); +} + +/* + * more--display the file. + */ +more(file) +char *file; +{ + FILE *fp; + int line; + char linebuf[1024]; + + if ((fp = fopen(file, "r")) == NULL) { + perror(file); + return; + } + + /* + * Print 22 lines at a time. + */ + for (;;) { + line = 1; + while (line < 22) { + /* + * If end-of-file, let them hit a key one + * more time and then go back. + */ + if (fgets(linebuf, sizeof(linebuf), fp) == NULL) { + fclose(fp); + prompt(); + return; + } + + fwrite(linebuf, 1, strlen(linebuf), stdout); + line++; + } + + prompt(); + } +} + +/* + * prompt--prompt for a character. + */ +prompt() +{ + char answer; + + printf("Type any character for next page: "); + answer = getchar(); + putchar('\n'); +} + diff --git a/reference/C/CONTRIB/OR_USING_C/05.2.c b/reference/C/CONTRIB/OR_USING_C/05.2.c new file mode 100644 index 0000000..592e474 --- /dev/null +++ b/reference/C/CONTRIB/OR_USING_C/05.2.c @@ -0,0 +1,101 @@ +#include +#include + +main(argc, argv) +int argc; +char **argv; +{ + struct termio tio, tin; + + if (argc < 2) { + fprintf(stderr, "Usage: %s file [file ...]\n", *argv); + exit(1); + } + + /* + * In real life we'd check the return value of + * this, since if the input is redirected from a + * file it will fail. We are assuming the + * terminal is always connected to the standard + * input. + */ + ioctl(0, TCGETA, &tio); + + tin = tio; + tin.c_lflag &= ~ECHO; /* turn off ECHO */ + tin.c_lflag &= ~ICANON; /* turn off ICANON */ + + /* + * Emulate CBREAK mode. + */ + tin.c_cc[VMIN] = 1; + tin.c_cc[VTIME] = 0; + + /* + * Set the new modes. Again we ignore return + * values. + */ + ioctl(0, TCSETA, &tin); + + while (--argc) + more(*++argv); + + /* + * Reset the old tty modes. + */ + ioctl(0, TCSETA, &tio); + + exit(0); +} + +/* + * more--display the file. + */ +more(file) +char *file; +{ + FILE *fp; + int line; + char linebuf[1024]; + + if ((fp = fopen(file, "r")) == NULL) { + perror(file); + return; + } + + /* + * Print 22 lines at a time. + */ + for (;;) { + line = 1; + while (line < 22) { + /* + * If end-of-file, let them hit a key one + * more time and then go back. + */ + if (fgets(linebuf, sizeof(linebuf), fp) == NULL) { + fclose(fp); + prompt(); + return; + } + + fwrite(linebuf, 1, strlen(linebuf), stdout); + line++; + } + + prompt(); + } +} + +/* + * prompt--prompt for a character. + */ +prompt() +{ + char answer; + + printf("Type any character for next page: "); + answer = getchar(); + putchar('\n'); +} + diff --git a/reference/C/CONTRIB/OR_USING_C/05.3.c b/reference/C/CONTRIB/OR_USING_C/05.3.c new file mode 100644 index 0000000..9457d07 --- /dev/null +++ b/reference/C/CONTRIB/OR_USING_C/05.3.c @@ -0,0 +1,61 @@ +#include +#include +#include + +main() +{ + int n, nfds; + char buf[32]; + fd_set readfds; + struct timeval tv; + + /* + * We will be reading from standard input (file + * descriptor 0), so we want to know when the + * user has typed something. + */ + FD_ZERO(&readfds); + FD_SET(0, &readfds); + + /* + * Set the timeout for 15 seconds. + */ + tv.tv_sec = 15; + tv.tv_usec = 0; + + /* + * Prompt for input. + */ + printf("Type a word; if you don't in 15 "); + printf("seconds I'll use \"WORD\": "); + fflush(stdout); + + /* + * Now call select. We pass NULL for + * writefds and exceptfds, since we + * aren't interested in them. + */ + nfds = select(1, &readfds, NULL, NULL, &tv); + + /* + * Now we check the results. If nfds is zero, + * then we timed out, and should assume the + * default. Otherwise, if file descriptor 0 + * is set in readfds, that means that it is + * ready to be read, and we can read something + * from it. + */ + if (nfds == 0) { + strcpy(buf, "WORD"); + } + else { + if (FD_ISSET(0, &readfds)) { + n = read(0, buf, sizeof(buf)); + buf[n-1] = '\0'; + } + } + + printf("\nThe word is: %s\n", buf); + exit(0); +} + diff --git a/reference/C/CONTRIB/OR_USING_C/06.1.c b/reference/C/CONTRIB/OR_USING_C/06.1.c new file mode 100644 index 0000000..2efc718 --- /dev/null +++ b/reference/C/CONTRIB/OR_USING_C/06.1.c @@ -0,0 +1,58 @@ +#include +#include +#include + +#define UTMP "/etc/utmp" +#define NAMELEN 8 + +main() +{ + FILE *fp; + struct utmp u; + struct passwd *p; + char tmp[NAMELEN+1]; + struct passwd *getpwnam(); + + if ((fp = fopen(UTMP, "r")) == NULL) { + perror(UTMP); + exit(1); + } + + /* + * For each entry... + */ + while (fread(&u, sizeof(u), 1, fp) != NULL) { + /* + * Skip non-logged in ports. + */ + if (u.ut_name[0] == NULL) + continue; + + /* + * Make sure name is null-terminated. + */ + strncpy(tmp, u.ut_name, NAMELEN); + + /* + * Skip non-existent users (shouldn't + * be any). + */ + if ((p = getpwnam(tmp)) == NULL) + continue; + + /* + * Print the line. ctime() converts the time + * to ASCII format, it is described in Chapter + * 7, Telling Time and Timing Things. We + * ignore the format of the gecos field and + * just print the first 30 characters; in real + * life we would stop at a comma or some such. + */ + printf("%-10.8s %-10.8s %-30.30s %s", u.ut_name, + u.ut_line, p->pw_gecos, ctime(&u.ut_time)); + } + + fclose(fp); + exit(0); +} + diff --git a/reference/C/CONTRIB/OR_USING_C/07.1.c b/reference/C/CONTRIB/OR_USING_C/07.1.c new file mode 100644 index 0000000..19ae68e --- /dev/null +++ b/reference/C/CONTRIB/OR_USING_C/07.1.c @@ -0,0 +1,21 @@ +#include +#include + +main() +{ + struct tms before, after; + + times(&before); + + /* ... place code to be timed here ... */ + + times(&after); + + printf("User time: %ld seconds\n", after.tms_utime - + before.tms_utime); + printf("System time: %ld seconds\n", after.tms_stime - + before.tms_stime); + + exit(0); +} + diff --git a/reference/C/CONTRIB/OR_USING_C/08.1.c b/reference/C/CONTRIB/OR_USING_C/08.1.c new file mode 100644 index 0000000..3a5cf10 --- /dev/null +++ b/reference/C/CONTRIB/OR_USING_C/08.1.c @@ -0,0 +1,13 @@ +#include + +main() +{ + signal(SIGINT, SIG_IGN); + + /* + * pause() just suspends the process until a + * signal is received. + */ + pause(); +} + diff --git a/reference/C/CONTRIB/OR_USING_C/08.2.c b/reference/C/CONTRIB/OR_USING_C/08.2.c new file mode 100644 index 0000000..e54d99d --- /dev/null +++ b/reference/C/CONTRIB/OR_USING_C/08.2.c @@ -0,0 +1,36 @@ +#include + +main() +{ + /* + * Declare handler routine so we can use its name. + */ + extern int handler(); + + /* + * Send signal to handler routine. + */ + signal(SIGINT, handler); + + /* + * Loop here. + */ + for (;;) + pause(); +} + +/* + * handler--handle the signal. + */ +handler() +{ + /* + * Users of 4.2 and 4.3BSD systems should un-comment + * this line, which will make this program + * behave as if it were on a non-Berkeley system. + */ + /* signal(SIGINT, SIG_DFL); */ + + printf("OUCH\n"); +} + diff --git a/reference/C/CONTRIB/OR_USING_C/08.3.c b/reference/C/CONTRIB/OR_USING_C/08.3.c new file mode 100644 index 0000000..d6ec5f2 --- /dev/null +++ b/reference/C/CONTRIB/OR_USING_C/08.3.c @@ -0,0 +1,42 @@ +#include + +main() +{ + /* + * Declare handler routine so we can use its + * name. + */ + extern int handler(); + + /* + * Send signal to handler routine. + */ + signal(SIGINT, handler); + + /* + * Loop here. + */ + for (;;) + pause(); +} + +/* + * handler--handle the signal. + */ +handler() +{ + /* + * Users of 4.2 and 4.3BSD systems should un-comment + * this line, which will make this program + * behave as if it were on a non-Berkeley system. + */ + /* signal(SIGINT, SIG_DFL); */ + + printf("OUCH\n"); + + /* + * Reset the signal to come here again. + */ + signal(SIGINT, handler); +} + diff --git a/reference/C/CONTRIB/OR_USING_C/08.4.c b/reference/C/CONTRIB/OR_USING_C/08.4.c new file mode 100644 index 0000000..3bcc96c --- /dev/null +++ b/reference/C/CONTRIB/OR_USING_C/08.4.c @@ -0,0 +1,47 @@ +#include + +main() +{ + /* + * Declare handler routine so we can use its + * name. + */ + extern int handler(); + /* + * Send signal to handler routine. Only do so + * if the signal is not already being ignored. + */ + if (signal(SIGINT, SIG_IGN) != SIG_IGN) + signal(SIGINT, handler); + /* + * Loop here. + */ + for (;;) + pause(); +} +/* + * handler--handle the signal. sig is the signal + * number which interrupted us. + */ +handler(sig) +int sig; +{ + /* + * Users of 4.2 and 4.3BSD systems should un-comment + * this line, which will make this program + * behave as if it were on a non-Berkeley + * system (we reset the signal by hand). + */ + /* signal(sig, SIG_DFL); */ + /* + * Ignore the signal for the duration of this + * routine. + */ + signal(sig, SIG_IGN); + printf("OUCH\n"); + /* + * Reset the signal to come here again. + */ + signal(SIGINT, handler); +} + diff --git a/reference/C/CONTRIB/OR_USING_C/08.5.c b/reference/C/CONTRIB/OR_USING_C/08.5.c new file mode 100644 index 0000000..47b0402 --- /dev/null +++ b/reference/C/CONTRIB/OR_USING_C/08.5.c @@ -0,0 +1,85 @@ +#include +#include + +/* + * The environment for setjmp. + */ +jmp_buf env; + +main() +{ + int i; + char buf[16]; + extern int timeout(); + + /* + * Inform the system we want to catch the + * alarm signal. + */ + signal(SIGALRM, timeout); + + /* + * The code inside the if gets executed the first + * time through setjmp, the code inside the else + * the second time. + */ + if (setjmp(env) == 0) { + /* + * Issue a request for an alarm to be + * delivered in 15 seconds. + */ + alarm(15); + + /* + * Prompt for input. + */ + printf("Type a word; if you don't in 15 "); + printf("seconds I'll use \"WORD\": "); + gets(buf); + + /* + * Turn off the alarm. + */ + alarm(0); + } + else { + /* + * Assume the default. + */ + strcpy(buf, "WORD"); + } + + printf("\nThe word is: %s\n", buf); + exit(0); +} + +/* + * timeout--catch the signal. + */ +timeout(sig) +int sig; +{ + /* + * Ignore the signal for the duration of this + * routine. + */ + signal(sig, SIG_IGN); + + /* + * We would perform any timeout-related + * functions here; in this case there + * are none. + */ + + /* + * Restore the action of the alarm signal. + */ + signal(SIGALRM, timeout); + + /* + * Return to the main routine at setjmp, + * and make setjmp return 1. + */ + longjmp(env, 1); +} + diff --git a/reference/C/CONTRIB/OR_USING_C/08.6.c b/reference/C/CONTRIB/OR_USING_C/08.6.c new file mode 100644 index 0000000..80ccd1e --- /dev/null +++ b/reference/C/CONTRIB/OR_USING_C/08.6.c @@ -0,0 +1,33 @@ +#include + +/* + * work, work, work, all I ever do is work! + */ +dowork() +{ +} + +main() +{ + int mask; + + /* + * Block SIGIO, which will indicate more + * work to be done. + */ + mask = sigmask(SIGIO); + + for (;;) { + /* + * Go do work. + */ + dowork(); + + /* + * Pause until we receive a signal. + * SIGIO is not blocked in mask. + */ + sigpause(mask); + } +} + diff --git a/reference/C/CONTRIB/OR_USING_C/08.7.c b/reference/C/CONTRIB/OR_USING_C/08.7.c new file mode 100644 index 0000000..5518c96 --- /dev/null +++ b/reference/C/CONTRIB/OR_USING_C/08.7.c @@ -0,0 +1,108 @@ +#include +#include +#include +#include +#include + +char *stack; /* pointer to signal stack base */ +int tooksig = 0; /* 1 after we take the signal */ + +main() +{ + extern void x(); + struct sigvec sv; + struct sigstack ss; + struct rlimit rlimit; + + /* + * Set stack size limit to 50 kbytes. + */ + getrlimit(RLIMIT_STACK, &rlimit); + rlimit.rlim_cur = 50 * 1024; + + if (setrlimit(RLIMIT_STACK, &rlimit) < 0) { + perror("setrlimit"); + exit(1); + } + + /* + * Take illegal instruction and process it with x, + * on the interrupt stack. For 4.2BSD, change + * sv_flags to sv_onstack and SV_ONSTACK to 1. + */ + sv.sv_mask = 0; + sv.sv_handler = x; + sv.sv_flags = SV_ONSTACK; + sigvec(SIGILL, &sv, (struct sigvec *) 0); + + /* + * Allocate memory for the signal stack. The + * kernel assumes the addresses grow in the same + * direction as on the process stack (toward + * lower addresses, on a VAX). + */ + if ((stack = (char *) malloc(10240)) == NULL) { + fprintf(stderr, "Out of memory.\n"); + exit(1); + } + + /* + * Issue the call to tell the system about the + * signal stack. We pass the end of the signal + * stack, not the beginning, since the stack + * grows toward lower addresses. + */ + ss.ss_onstack = 0; + ss.ss_sp = (caddr_t) stack + 10240; + + if (sigstack(&ss, (struct sigstack *) 0) < 0) { + perror("sigstack"); + exit(1); + } + + /* + * Start using up stack space. + */ + y(); +} + +y() +{ + /* + * Take up 5k of stack space. + */ + char buf[5120]; + + printf("%s\n", tooksig ? "Now on extended stack." : + "On 50k stack."); + + /* + * Recurse. + */ + y(); +} + +/* + * Handle the signal. + */ +void x(sig, code, scp) +int sig, code; +struct sigcontext *scp; +{ + struct rlimit rlimit; + + /* + * Increase the stack limit to the maximum. + */ + getrlimit(RLIMIT_STACK, &rlimit); + rlimit.rlim_cur = rlimit.rlim_max; + + if (setrlimit(RLIMIT_STACK, &rlimit) < 0) { + perror("setrlimit"); + exit(1); + } + + tooksig = 1; + return; +} + diff --git a/reference/C/CONTRIB/OR_USING_C/09.1.c b/reference/C/CONTRIB/OR_USING_C/09.1.c new file mode 100644 index 0000000..035186d --- /dev/null +++ b/reference/C/CONTRIB/OR_USING_C/09.1.c @@ -0,0 +1,95 @@ +#include + +main() +{ + char buf[1024]; + char *args[64]; + + for (;;) { + /* + * Prompt for and read a command. + */ + printf("Command: "); + + if (gets(buf) == NULL) { + printf("\n"); + exit(0); + } + + /* + * Split the string into arguments. + */ + parse(buf, args); + + /* + * Execute the command. + */ + execute(args); + } +} + +/* + * parse--split the command in buf into + * individual arguments. + */ +parse(buf, args) +char *buf; +char **args; +{ + while (*buf != NULL) { + /* + * Strip whitespace. Use nulls, so + * that the previous argument is terminated + * automatically. + */ + while ((*buf == ' ') || (*buf == '\t')) + *buf++ = NULL; + + /* + * Save the argument. + */ + *args++ = buf; + + /* + * Skip over the argument. + */ + while ((*buf != NULL) && (*buf != ' ') && (*buf != '\t')) + buf++; + } + + *args = NULL; +} + +/* + * execute--spawn a child process and execute + * the program. + */ +execute(args) +char **args; +{ + int pid, status; + + /* + * Get a child process. + */ + if ((pid = fork()) < 0) { + perror("fork"); + exit(1); + } + + /* + * The child executes the code inside the if. + */ + if (pid == 0) { + execvp(*args, args); + perror(*args); + exit(1); + } + + /* + * The parent executes the wait. + */ + while (wait(&status) != pid) + /* empty */ ; +} + diff --git a/reference/C/CONTRIB/OR_USING_C/09.2.c b/reference/C/CONTRIB/OR_USING_C/09.2.c new file mode 100644 index 0000000..82ad2bb --- /dev/null +++ b/reference/C/CONTRIB/OR_USING_C/09.2.c @@ -0,0 +1,52 @@ +execute(args, sin, sout, serr) +char **args; +int sin, sout, serr; +{ + int pid, status; + + /* + * Get a child process. + */ + if ((pid = fork()) < 0) { + perror("fork"); + exit(1); + } + + /* + * The child executes the code inside the if. + */ + if (pid == 0) { + /* + * For each of standard input, output, + * and error output, set the child's + * to the passed-down file descriptor. + * Note that we can't just close 0, 1, + * and 2 since we might need them. + */ + if (sin != 0) { + close(0); + dup(sin); /* will give us fd #0 */ + } + + if (sout != 1) { + close(1); + dup(sout); /* will give us fd #1 */ + } + + if (serr != 2) { + close(2); + dup(serr); /* will give us fd #2 */ + } + + execvp(*args, args); + perror(*args); + exit(1); + } + + /* + * The parent executes the wait. + */ + while (wait(&status) != pid) + /* empty loop */; +} + diff --git a/reference/C/CONTRIB/OR_USING_C/09.3.c b/reference/C/CONTRIB/OR_USING_C/09.3.c new file mode 100644 index 0000000..25b6e44 --- /dev/null +++ b/reference/C/CONTRIB/OR_USING_C/09.3.c @@ -0,0 +1,87 @@ +#include + +main() +{ + FILE *fp; + int pid, pipefds[2]; + char *username, *getlogin(); + + /* + * Get the user's name. + */ + if ((username = getlogin()) == NULL) { + fprintf(stderr, "Who are you?\n"); + exit(1); + } + + /* + * Create the pipe. This has to be done + * BEFORE the fork. + */ + if (pipe(pipefds) < 0) { + perror("pipe"); + exit(1); + } + + if ((pid = fork()) < 0) { + perror("fork"); + exit(1); + } + + /* + * The child process executes the stuff inside + * the if. + */ + if (pid == 0) { + /* + * Make the read side of the pipe our + * standard input. + */ + close(0); + dup(pipefds[0]); + close(pipefds[0]); + + /* + * Close the write side of the pipe; + * we'll let our output go to the screen. + */ + close(pipefds[1]); + /* + * Execute the command "mail username". + */ + execl("/bin/mail", "mail", username, 0); + perror("exec"); + exit(1); + } + + /* + * The parent executes this code. + */ + + /* + * Close the read side of the pipe; we + * don't need it (and the child is not + * writing on the pipe anyway). + */ + close(pipefds[0]); + + /* + * Convert the write side of the pipe to stdio. + */ + fp = fdopen(pipefds[1], "w"); + + /* + * Send a message, close the pipe. + */ + fprintf(fp, "Hello from your program.\n"); + fclose(fp); + + /* + * Wait for the process to terminate. + */ + while (wait((int *) 0) != pid) + ; + + exit(0); +} + diff --git a/reference/C/CONTRIB/OR_USING_C/09.4.c b/reference/C/CONTRIB/OR_USING_C/09.4.c new file mode 100644 index 0000000..dba1cd6 --- /dev/null +++ b/reference/C/CONTRIB/OR_USING_C/09.4.c @@ -0,0 +1,91 @@ +/* + * mailer - open a pipe to the mail command and send the user + * mail. + */ +#include + +main() +{ + FILE *fp; + int pid, pipefds[2]; + char *username, *getlogin(); + + /* + * Get the user's name. + */ + if ((username = getlogin()) == NULL) { + fprintf(stderr, "Who are you?\n"); + exit(1); + } + + /* + * Create the pipe. This has to be done + * BEFORE the fork. + */ + if (pipe(pipefds) < 0) { + perror("pipe"); + exit(1); + } + + if ((pid = fork()) < 0) { + perror("fork"); + exit(1); + } + + /* + * The child process executes the stuff inside + * the if. + */ + if (pid == 0) { + /* + * Make the read side of the pipe our + * standard input. + */ + close(0); + dup(pipefds[0]); + close(pipefds[0]); + + /* + * Close the write side of the pipe; + * we'll let our output go to the screen. + */ + close(pipefds[1]); + + /* + * Execute the command "mail username". + */ + execl("/bin/mail", "mail", username, 0); + perror("exec"); + exit(1); + } + + /* + * The parent executes this code. + */ + + /* + * Close the read side of the pipe; we + * don't need it (and the child is not + * writing on the pipe anyway). + */ + close(pipefds[0]); + + /* + * Convert the write side of the pipe to stdio. + */ + fp = fdopen(pipefds[1], "w"); + + /* + * Send a message, close the pipe. + */ + fprintf(fp, "Hello from your program.\n"); + fclose(fp); + + /* + * Wait for the process to terminate. + */ + while (wait((int *) 0) != pid) + ; + + exit(0); +} diff --git a/reference/C/CONTRIB/OR_USING_C/10.1.c b/reference/C/CONTRIB/OR_USING_C/10.1.c new file mode 100644 index 0000000..999d4d3 --- /dev/null +++ b/reference/C/CONTRIB/OR_USING_C/10.1.c @@ -0,0 +1,39 @@ +#include +#include "10.h" + +int MyPid; /* the shell's process id */ +int MyPgrp; /* the shell's process group */ +int TermPgrp; /* the terminal's process group */ + +setup() +{ + /* + * Obtain shell's process id. + */ + MyPid = getpid(); + + /* + * Just use pid for process group. This is + * not a requirement, just convenient. Other + * ways of picking a process group can be used. + */ + MyPgrp = MyPid; + TermPgrp = MyPid; + + /* + * Set the shell's process group. + */ + if (setpgrp(MyPid, MyPgrp) < 0) { + perror("setpgrp"); + exit(1); + } + + /* + * Set the terminal's process group. + */ + if (ioctl(1, TIOCSPGRP, &MyPgrp) < 0) { + perror("ioctl"); + exit(1); + } +} + diff --git a/reference/C/CONTRIB/OR_USING_C/10.2.c b/reference/C/CONTRIB/OR_USING_C/10.2.c new file mode 100644 index 0000000..c9ee9dd --- /dev/null +++ b/reference/C/CONTRIB/OR_USING_C/10.2.c @@ -0,0 +1,37 @@ +#include +#include +#include "10.h" + +stop(j) +JOB *j; +{ + /* + * If the job is already stopped, we don't + * need to do anything. + */ + if (j->status & JSTOPPED) + return; + + /* + * If the job's process group is not that of the + * terminal, then the job is in the background + * and must be sent a stop signal. + */ + if (j->pgrp != TermPgrp) + killpg(j->pgrp, SIGSTOP); + + /* + * Mark the job as stopped. + */ + j->status |= JSTOPPED; + + /* + * If the terminal is not in the shell's process + * group, we need to put it there. + */ + if (TermPgrp != MyPgrp) { + ioctl(1, TIOCSPGRP, &MyPgrp); + TermPgrp = MyPgrp; + } +} + diff --git a/reference/C/CONTRIB/OR_USING_C/10.3.c b/reference/C/CONTRIB/OR_USING_C/10.3.c new file mode 100644 index 0000000..b5179cf --- /dev/null +++ b/reference/C/CONTRIB/OR_USING_C/10.3.c @@ -0,0 +1,26 @@ +#include +#include +#include "10.h" + +bg(j) +JOB *j; +{ + /* + * If the job is already running, + * there's no need to start it. + */ + if (j->status & JRUNNING) + return; + + /* + * Start the job. + */ + killpg(j->pgrp, SIGCONT); + + /* + * Mark the job as running. + */ + j->status &= ~JSTOPPED; + j->status |= JRUNNING; +} + diff --git a/reference/C/CONTRIB/OR_USING_C/10.4.c b/reference/C/CONTRIB/OR_USING_C/10.4.c new file mode 100644 index 0000000..48cbdc7 --- /dev/null +++ b/reference/C/CONTRIB/OR_USING_C/10.4.c @@ -0,0 +1,32 @@ +#include +#include +#include "10.h" + +fg(j) +JOB *j; +{ + /* + * If the terminal is not in the job's process + * group, change the process group of the + * terminal. + */ + if (j->pgrp != TermPgrp) { + ioctl(1, TIOCSPGRP, &j->pgrp); + TermPgrp = j->pgrp; + } + + /* + * If the job is not running, start it up. + */ + if (j->status & JSTOPPED) { + killpg(j->pgrp, SIGCONT); + j->status &= ~JSTOPPED; + j->status |= JRUNNING; + } + + /* + * Go wait for the job to complete. + */ + waitfor(); +} + diff --git a/reference/C/CONTRIB/OR_USING_C/10.5.c b/reference/C/CONTRIB/OR_USING_C/10.5.c new file mode 100644 index 0000000..df6140b --- /dev/null +++ b/reference/C/CONTRIB/OR_USING_C/10.5.c @@ -0,0 +1,132 @@ +#include +#include +#include +#include "10.h" + +waitfor() +{ + int pid; + JOB *j; + PROC *p; + JOB *findjob(); + union wait status; + + /* + * As long as we get something's status back... + */ + while ((pid = wait3(&status, WUNTRACED, 0)) >= 0) { + /* + * Find the job structure which has this + * process. + */ + j = findjob(pid); + + /* + * Find the process structure. + */ + for (p = j->procs; p->pid != pid; p = p->next) + /* empty */ ; + + /* + * Find out what happened to the process. + */ + if (WIFSTOPPED(status)) { + /* + * See if we know the reason it was + * stopped. The w_stopsig element of + * the structure contains the number + * of the signal which stopped the + * process. + */ + switch (status.w_stopsig) { + case SIGTTIN: + p->status |= PTTYINPUT; + break; + case SIGTTOU: + p->status |= PTTYOUTPUT; + break; + case SIGSTOP: + p->status |= PSTOPSIGNAL; + break; + default: + break; + } + + p->status |= PSTOPPED; + j->status |= JNEEDNOTE; + } + else if (WIFEXITED(status)) { + /* + * Normal termination. + */ + if (status.w_retcode == 0) + p->status |= PDONE; + else + p->status |= PEXITED; + + p->exitcode = status.w_retcode; + + /* + * We're only going to note processes + * exiting if all the processes in the + * job are complete. + */ + if (alldone(j)) + j->status |= JNEEDNOTE; + } + else if (WIFSIGNALED(status)) { + p->status |= PSIGNALED; + + /* + * Save the termination signal. + */ + p->termsig = status.w_termsig; + + /* + * Check for a core dump. + */ + if (status.w_coredump) + p->status |= PCOREDUMP; + + /* + * We're only going to note processes + * exiting if all the processes in the + * job are complete. + */ + if (alldone(j)) + j->status |= JNEEDNOTE; + } + + /* + * If this process is the one which was in the + * foreground, we need to do special things, + * and then return to the main control section + * of the shell. + */ + if (j->pgrp == TermPgrp) { + /* + * If the job is stopped, we need to call + * the stop routine. + */ + if (WIFSTOPPED(status)) { + stop(j); + printf("Stopped\n"); + } + + /* + * If the job exited or died somehow, we + * need to regain control of the terminal. + */ + if (WIFEXITED(status) || WIFSIGNALED(status)) { + ioctl(1, TIOCSPGRP, &MyPgrp); + TermPgrp = MyPgrp; + } + + /* + * Go back. + */ + return; + } + } +} + diff --git a/reference/C/CONTRIB/OR_USING_C/10.h b/reference/C/CONTRIB/OR_USING_C/10.h new file mode 100644 index 0000000..87e0054 --- /dev/null +++ b/reference/C/CONTRIB/OR_USING_C/10.h @@ -0,0 +1,34 @@ + +extern int MyPid; /* the shell's process id */ +extern int MyPgrp; /* the shell's process group */ +extern int TermPgrp; /* the terminal's process group */ + +#define JSTOPPED (1L<<1) +#define JRUNNING (1L<<2) +#define JNEEDNOTE (1L<<3) + +#define PTTYINPUT (1L<<1) +#define PTTYOUTPUT (1L<<2) +#define PSTOPSIGNAL (1L<<3) +#define PSTOPPED (1L<<4) +#define PDONE (1L<<5) +#define PEXITED (1L<<6) +#define PCOREDUMP (1L<<7) +#define PSIGNALED (1L<<8) + +struct _PROC { + int pid; + int status; + int exitcode; + int termsig; + struct _PROC *next; +}; +typedef struct _PROC PROC; + +struct _JOB { + int status; + int pgrp; + PROC *procs; +}; +typedef struct _JOB JOB; + diff --git a/reference/C/CONTRIB/OR_USING_C/11.1.c b/reference/C/CONTRIB/OR_USING_C/11.1.c new file mode 100644 index 0000000..34be61e --- /dev/null +++ b/reference/C/CONTRIB/OR_USING_C/11.1.c @@ -0,0 +1,91 @@ +#include +#include +#include +#include + +#define NSTRS 3 /* no. of strings */ +#define ADDRESS "mysocket" /* addr to connect */ + +/* + * Strings we send to the server. + */ +char *strs[NSTRS] = { + "This is the first string from the client.\n", + "This is the second string from the client.\n", + "This is the third string from the client.\n" +}; + +main() +{ + char c; + FILE *fp; + register int i, s, len; + struct sockaddr_un saun; + + /* + * Get a socket to work with. This socket will + * be in the UNIX domain, and will be a + * stream socket. + */ + if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { + perror("client: socket"); + exit(1); + } + + /* + * Create the address we will be connecting to. + */ + saun.sun_family = AF_UNIX; + strcpy(saun.sun_path, ADDRESS); + + /* + * Try to connect to the address. For this to + * succeed, the server must already have bound + * this address, and must have issued a listen() + * request. + * + * The third argument indicates the "length" of + * the structure, not just the length of the + * socket name. + */ + len = sizeof(saun.sun_family) + strlen(saun.sun_path); + + if (connect(s, &saun, len) < 0) { + perror("client: connect"); + exit(1); + } + + /* + * We'll use stdio for reading + * the socket. + */ + fp = fdopen(s, "r"); + + /* + * First we read some strings from the server + * and print them out. + */ + for (i = 0; i < NSTRS; i++) { + while ((c = fgetc(fp)) != EOF) { + putchar(c); + + if (c == '\n') + break; + } + } + + /* + * Now we send some strings to the server. + */ + for (i = 0; i < NSTRS; i++) + send(s, strs[i], strlen(strs[i]), 0); + + /* + * We can simply use close() to terminate the + * connection, since we're done with both sides. + */ + close(s); + + exit(0); +} + diff --git a/reference/C/CONTRIB/OR_USING_C/11.2.c b/reference/C/CONTRIB/OR_USING_C/11.2.c new file mode 100644 index 0000000..18140aa --- /dev/null +++ b/reference/C/CONTRIB/OR_USING_C/11.2.c @@ -0,0 +1,109 @@ +#include +#include +#include +#include + +#define NSTRS 3 /* no. of strings */ +#define ADDRESS "mysocket" /* addr to connect */ + +/* + * Strings we send to the client. + */ +char *strs[NSTRS] = { + "This is the first string from the server.\n", + "This is the second string from the server.\n", + "This is the third string from the server.\n" +}; + +main() +{ + char c; + FILE *fp; + int fromlen; + register int i, s, ns, len; + struct sockaddr_un saun, fsaun; + + /* + * Get a socket to work with. This socket will + * be in the UNIX domain, and will be a + * stream socket. + */ + if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { + perror("server: socket"); + exit(1); + } + + /* + * Create the address we will be binding to. + */ + saun.sun_family = AF_UNIX; + strcpy(saun.sun_path, ADDRESS); + + /* + * Try to bind the address to the socket. We + * unlink the name first so that the bind won't + * fail. + * + * The third argument indicates the "length" of + * the structure, not just the length of the + * socket name. + */ + unlink(ADDRESS); + len = sizeof(saun.sun_family) + strlen(saun.sun_path); + + if (bind(s, &saun, len) < 0) { + perror("server: bind"); + exit(1); + } + + /* + * Listen on the socket. + */ + if (listen(s, 5) < 0) { + perror("server: listen"); + exit(1); + } + + /* + * Accept connections. When we accept one, ns + * will be connected to the client. fsaun will + * contain the address of the client. + */ + if ((ns = accept(s, &fsaun, &fromlen)) < 0) { + perror("server: accept"); + exit(1); + } + + /* + * We'll use stdio for reading the socket. + */ + fp = fdopen(ns, "r"); + + /* + * First we send some strings to the client. + */ + for (i = 0; i < NSTRS; i++) + send(ns, strs[i], strlen(strs[i]), 0); + + /* + * Then we read some strings from the client and + * print them out. + */ + for (i = 0; i < NSTRS; i++) { + while ((c = fgetc(fp)) != EOF) { + putchar(c); + + if (c == '\n') + break; + } + } + + /* + * We can simply use close() to terminate the + * connection, since we're done with both sides. + */ + close(s); + + exit(0); +} + diff --git a/reference/C/CONTRIB/OR_USING_C/11.3.c b/reference/C/CONTRIB/OR_USING_C/11.3.c new file mode 100644 index 0000000..25d6e05 --- /dev/null +++ b/reference/C/CONTRIB/OR_USING_C/11.3.c @@ -0,0 +1,63 @@ +#include +#include +#include +#include + +#define MSGSZ 128 + +#ifdef NOT_USED +/* + * Declare the message structure. + */ +struct msgbuf { + long mtype; + char mtext[MSGSZ]; +}; +#endif /* NOT_USED */ + +main() +{ + int msqid; + key_t key; + struct msgbuf sbuf, rbuf; + + /* + * Create a message queue with "name" 1234. + */ + key = 1234; + + /* + * We want to let everyone read and + * write on this message queue, hence + * we use 0666 as the permissions. + */ + if ((msqid = msgget(key, IPC_CREAT | 0666)) < 0) { + perror("msgget"); + exit(1); + } + + /* + * Receive a message. + */ + if (msgrcv(msqid, &rbuf, MSGSZ, 0, 0) < 0) { + perror("msgrcv"); + exit(1); + } + + /* + * We send a message of type 2. + */ + sbuf.mtype = 2; + sprintf(sbuf.mtext, "I received your message."); + + /* + * Send an answer. + */ + if (msgsnd(msqid, &sbuf, strlen(sbuf.mtext) + 1, 0) < 0) { + perror("msgsnd"); + exit(1); + } + + exit(0); +} + diff --git a/reference/C/CONTRIB/OR_USING_C/11.4.c b/reference/C/CONTRIB/OR_USING_C/11.4.c new file mode 100644 index 0000000..346e577 --- /dev/null +++ b/reference/C/CONTRIB/OR_USING_C/11.4.c @@ -0,0 +1,65 @@ +#include +#include +#include +#include + +#define MSGSZ 128 + +#ifdef NOT_USED +/* + * Declare the message structure. + */ +struct msgbuf { + long mtype; + char mtext[MSGSZ]; +}; +#endif /* NOT_USED */ + +main() +{ + int msqid; + key_t key; + struct msgbuf sbuf, rbuf; + + /* + * Get the message queue id for the + * "name" 1234, which was created by + * the server. + */ + key = 1234; + + if ((msqid = msgget(key, 0666)) < 0) { + perror("msgget"); + exit(1); + } + + /* + * We'll send message type 1, the server + * will send message type 2. + */ + sbuf.mtype = 1; + sprintf(sbuf.mtext, "Did you get this?"); + + /* + * Send a message. + */ + if (msgsnd(msqid, &sbuf, strlen(sbuf.mtext) + 1, 0) < 0) { + perror("msgsnd"); + exit(1); + } + + /* + * Receive an answer of message type 2. + */ + if (msgrcv(msqid, &rbuf, MSGSZ, 2, 0) < 0) { + perror("msgrcv"); + exit(1); + } + + /* + * Print the answer. + */ + printf("%s\n", rbuf.mtext); + exit(0); +} + diff --git a/reference/C/CONTRIB/OR_USING_C/11.5.c b/reference/C/CONTRIB/OR_USING_C/11.5.c new file mode 100644 index 0000000..50038de --- /dev/null +++ b/reference/C/CONTRIB/OR_USING_C/11.5.c @@ -0,0 +1,59 @@ +#include +#include +#include +#include + +#define SHMSZ 27 + +main() +{ + char c; + int shmid; + key_t key; + char *shmat(); + char *shm, *s; + + /* + * We'll name our shared memory segment + * "5678". + */ + key = 5678; + + /* + * Create the segment. + */ + if ((shmid = shmget(key, SHMSZ, IPC_CREAT | 0666)) < 0) { + perror("shmget"); + exit(1); + } + + /* + * Now we attach the segment to our data space. + */ + if ((shm = shmat(shmid, NULL, 0)) == (char *) -1) { + perror("shmat"); + exit(1); + } + + /* + * Now put some things into the memory for the + * other process to read. + */ + s = shm; + + for (c = 'a'; c <= 'z'; c++) + *s++ = c; + *s = NULL; + + /* + * Finally, we wait until the other process + * changes the first character of our memory + * to '*', indicating that it has read what + * we put there. + */ + while (*shm != '*') + sleep(1); + + exit(0); +} + diff --git a/reference/C/CONTRIB/OR_USING_C/11.6.c b/reference/C/CONTRIB/OR_USING_C/11.6.c new file mode 100644 index 0000000..7db84df --- /dev/null +++ b/reference/C/CONTRIB/OR_USING_C/11.6.c @@ -0,0 +1,53 @@ +#include +#include +#include +#include + +#define SHMSZ 27 + +main() +{ + int shmid; + key_t key; + char *shmat(); + char *shm, *s; + + /* + * We need to get the segment named + * "5678", created by the server. + */ + key = 5678; + + /* + * Locate the segment. + */ + if ((shmid = shmget(key, SHMSZ, 0666)) < 0) { + perror("shmget"); + exit(1); + } + + /* + * Now we attach the segment to our data space. + */ + if ((shm = shmat(shmid, NULL, 0)) == (char *) -1) { + perror("shmat"); + exit(1); + } + + /* + * Now read what the server put in the memory. + */ + for (s = shm; *s != NULL; s++) + putchar(*s); + putchar('\n'); + + /* + * Finally, change the first character of the + * segment to '*', indicating we have read + * the segment. + */ + *shm = '*'; + + exit(0); +} + diff --git a/reference/C/CONTRIB/OR_USING_C/11.7.c b/reference/C/CONTRIB/OR_USING_C/11.7.c new file mode 100644 index 0000000..c21a168 --- /dev/null +++ b/reference/C/CONTRIB/OR_USING_C/11.7.c @@ -0,0 +1,55 @@ +/* + * shm-client - client program to demonstrate shared memory. + */ +#include +#include +#include +#include + +#define SHMSZ 27 + +main() +{ + int shmid; + key_t key; + char *shmat(); + char *shm, *s; + + /* + * We need to get the segment named + * "5678", created by the server. + */ + key = 5678; + + /* + * Locate the segment. + */ + if ((shmid = shmget(key, SHMSZ, 0666)) < 0) { + perror("shmget"); + exit(1); + } + + /* + * Now we attach the segment to our data space. + */ + if ((shm = shmat(shmid, NULL, 0)) == (char *) -1) { + perror("shmat"); + exit(1); + } + + /* + * Now read what the server put in the memory. + */ + for (s = shm; *s != NULL; s++) + putchar(*s); + putchar('\n'); + + /* + * Finally, change the first character of the + * segment to '*', indicating we have read + * the segment. + */ + *shm = '*'; + + exit(0); +} diff --git a/reference/C/CONTRIB/OR_USING_C/12.1.c b/reference/C/CONTRIB/OR_USING_C/12.1.c new file mode 100644 index 0000000..3685c34 --- /dev/null +++ b/reference/C/CONTRIB/OR_USING_C/12.1.c @@ -0,0 +1,112 @@ +/* + * Connects to the local host at port 1234. + */ +#include +#include +#include +#include +#include + +#define NSTRS 3 /* no. of strings */ + +/* + * Strings we send to the server. + */ +char *strs[NSTRS] = { + "This is the first string from the client.\n", + "This is the second string from the client.\n", + "This is the third string from the client.\n" +}; + +extern int errno; + +main() +{ + char c; + FILE *fp; + char hostname[64]; + register int i, s; + struct hostent *hp; + struct sockaddr_in sin; + + /* + * Before we can do anything, we need to know + * our hostname. + */ + gethostname(hostname, sizeof(hostname)); + + /* + * Next, we need to look up the network + * address of our host. + */ + if ((hp = gethostbyname(hostname)) == NULL) { + fprintf(stderr, "%s: unknown host.\n", hostname); + exit(1); + } + + /* + * Get a socket to work with. This socket will + * be in the Internet domain, and will be a + * stream socket. + */ + if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + perror("client: socket"); + exit(1); + } + + /* + * Create the address we will be connecting to. + * We use port 1234 but put it into network + * byte order. Also, we use bcopy (see Chapter + * 14) to copy the network number. + */ + sin.sin_family = AF_INET; + sin.sin_port = htons(1234); + bcopy(hp->h_addr, &sin.sin_addr, hp->h_length); + + /* + * Try to connect to the address. For this to + * succeed, the server must already have bound + * this address, and must have issued a listen() + * request. + */ + if (connect(s, &sin, sizeof(sin)) < 0) { + perror("client: connect"); + exit(1); + } + + /* + * We'll use stdio for reading + * the socket. + */ + fp = fdopen(s, "r"); + + /* + * First we read some strings from the server + * and print them out. + */ + for (i = 0; i < NSTRS; i++) { + while ((c = fgetc(fp)) != EOF) { + putchar(c); + + if (c == '\n') + break; + } + } + + /* + * Now we send some strings to the server. + */ + for (i = 0; i < NSTRS; i++) + send(s, strs[i], strlen(strs[i]), 0); + + + /* + * We can simply use close() to terminate the + * connection, since we're done with both sides. + */ + close(s); + + exit(0); +} + diff --git a/reference/C/CONTRIB/OR_USING_C/12.2.c b/reference/C/CONTRIB/OR_USING_C/12.2.c new file mode 100644 index 0000000..ed64580 --- /dev/null +++ b/reference/C/CONTRIB/OR_USING_C/12.2.c @@ -0,0 +1,126 @@ +/* + * Connects to port 1234 on the local host. + */ +#include +#include +#include +#include +#include + +#define NSTRS 3 /* no. of strings */ + +/* + * Strings we send to the client. + */ +char *strs[NSTRS] = { + "This is the first string from the server.\n", + "This is the second string from the server.\n", + "This is the third string from the server.\n" +}; + +extern int errno; + +main() +{ + char c; + FILE *fp; + int fromlen; + char hostname[64]; + struct hostent *hp; + register int i, s, ns; + struct sockaddr_in sin, fsin; + + /* + * Before we can do anything, we need + * to know our hostname. + */ + gethostname(hostname, sizeof(hostname)); + + /* + * Now we look up our host to get + * its network number. + */ + if ((hp = gethostbyname(hostname)) == NULL) { + fprintf(stderr, "%s: host unknown.\n", hostname); + exit(1); + } + + /* + * Get a socket to work with. This socket will + * be in the Internet domain, and will be a + * stream socket. + */ + if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + perror("server: socket"); + exit(1); + } + + /* + * Create the address that we will be binding to. + * We use port 1234 but put it into network + * byte order. Also, we use bcopy (see + * Chapter 14) to copy the network number. + */ + sin.sin_family = AF_INET; + sin.sin_port = htons(1234); + bcopy(hp->h_addr, &sin.sin_addr, hp->h_length); + + /* + * Try to bind the address to the socket. + */ + if (bind(s, &sin, sizeof(sin)) < 0) { + perror("server: bind"); + exit(1); + } + + /* + * Listen on the socket. + */ + if (listen(s, 5) < 0) { + perror("server: listen"); + exit(1); + } + + /* + * Accept connections. When we accept one, ns + * will be connected to the client. fsin will + * contain the address of the client. + */ + if ((ns = accept(s, &fsin, &fromlen)) < 0) { + perror("server: accept"); + exit(1); + } + + /* + * We'll use stdio for reading the socket. + */ + fp = fdopen(ns, "r"); + + /* + * First we send some strings to the client. + */ + for (i = 0; i < NSTRS; i++) + send(ns, strs[i], strlen(strs[i]), 0); + + /* + * Then we read some strings from the client + * and print them out. + */ + for (i = 0; i < NSTRS; i++) { + while ((c = fgetc(fp)) != EOF) { + putchar(c); + + if (c == '\n') + break; + } + } + + /* + * We can simply use close() to terminate the + * connection, since we're done with both sides. + */ + close(s); + + exit(0); +} + diff --git a/reference/C/CONTRIB/OR_USING_C/12.3.c b/reference/C/CONTRIB/OR_USING_C/12.3.c new file mode 100644 index 0000000..50b755c --- /dev/null +++ b/reference/C/CONTRIB/OR_USING_C/12.3.c @@ -0,0 +1,93 @@ +#include +#include +#include +#include +#include + +#define BUFSZ 256 +#define SERVICE "daytime" + +main(argc, argv) +int argc; +char **argv; +{ + int s, n, len; + char buf[BUFSZ]; + struct hostent *hp; + struct servent *sp; + struct sockaddr_in sin; + + /* + * Get a datagram socket in the Internet + * domain. + */ + if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + perror("socket"); + exit(1); + } + + /* + * Look up the port number of the service. + */ + if ((sp = getservbyname(SERVICE, "udp")) == NULL) { + fprintf(stderr, "%s/udp: unknown service.\n", SERVICE); + exit(1); + } + + /* + * For each host on the command line... + */ + while (--argc) { + /* + * Look up the network number of + * the host. + */ + if ((hp = gethostbyname(*++argv)) == NULL) { + fprintf(stderr, "%s: host unknown.\n", *argv); + continue; + } + + /* + * Build the address of the server on + * the remote machine. + */ + sin.sin_family = AF_INET; + sin.sin_port = sp->s_port; + bcopy(hp->h_addr, &sin.sin_addr, hp->h_length); + + /* + * Print the name of the host. + */ + printf("%s: ", *argv); + fflush(stdout); + + /* + * Send a datagram to the server. + */ + if (sendto(s, buf, BUFSZ, 0, &sin, sizeof(sin)) < 0) { + perror("sendto"); + continue; + } + + /* + * Receive a datagram back. + */ + len = sizeof(sin); + n = recvfrom(s, buf, sizeof(buf), 0, &sin, &len); + + if (n < 0) { + perror("recvfrom"); + continue; + } + + /* + * Print the datagram. + */ + buf[n] = NULL; + printf("%s\n", buf); + } + + close(s); + exit(0); +} + diff --git a/reference/C/CONTRIB/OR_USING_C/13.1.c b/reference/C/CONTRIB/OR_USING_C/13.1.c new file mode 100644 index 0000000..27dbf67 --- /dev/null +++ b/reference/C/CONTRIB/OR_USING_C/13.1.c @@ -0,0 +1,254 @@ +/* + * Sys V version + * + * Reads the i-node structures from a raw disk + * device and then sums up the disk usage for + * each user. Prints out the number of blocks + * each user is using. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Maximum user id. + */ +#ifndef MAXUID +#define MAXUID 32768 +#endif + +#define SBSIZE BSIZE /* size of super-block */ +#define sblock sb_un.u_sblock + +/* + * The super-block. We allow enough room for + * a complete disk block. + */ +union { + char dummy[SBSIZE]; + struct filsys u_sblock; +} sb_un; + +int nfiles; /* no. of files in filsys */ + +char *pname; /* program name (argv[0]) */ +char *device; /* name of disk device */ +char *filsys; /* name of file system */ + +size_t blocks[MAXUID]; /* count of blocks used */ +struct dinode *dinode; /* will hold the i-nodes */ + +main(argc, argv) +int argc; +char **argv; +{ + int i, fd; + register ino_t ino; + register struct dinode *di; + + /* + * Save the program name and check our arguments. + */ + pname = *argv; + + if (argc != 2) { + fprintf(stderr, "Usage: %s raw-disk-device\n", pname); + exit(1); + } + + /* + * Open the device for reading. + */ + device = *++argv; + + if ((fd = open(device, O_RDONLY)) < 0) { + perror(device); + exit(1); + } + + /* + * Get the super-block from the device. + */ + getsblock(fd); + + /* + * Get the i-node structures from the device. + */ + getinodes(fd); + + close(fd); + + /* + * Zero the block counts. + */ + for (i = 0; i < MAXUID; i++) + blocks[i] = 0; + + /* + * Add up the number of blocks being used by each + * user id. + */ + for (ino = 0; ino < nfiles; ino++) { + /* + * ROOTINO is the first i-node; skip any + * before it. + */ + if (ino < ROOTINO) + continue; + + di = &dinode[ino]; + + /* + * If this is zero, the i-node is free (not + * in use). + */ + if ((di->di_mode & IFMT) == 0) + continue; + + /* + * Count the number of blocks being used by + * this file. We round the number of bytes to + * the next highest multiple of 512. + */ + blocks[di->di_uid] += (di->di_size + 511) / 512; + } + + /* + * Print out what we added up. + */ + printusage(); + exit(0); +} + +/* + * getsblock--get the super-block from the device referred + * to by fd. + */ +getsblock(fd) +int fd; +{ + /* + * Make sure the disk information is current. This + * causes all disk writes to be scheduled. + */ + sync(); + + /* + * Read in the super-block. It is stored at file + * system address SUPERBOFF. + */ + lseek(fd, (long) SUPERBOFF, 0); + read(fd, &sblock, SBSIZE); + + /* + * The number of files (i-nodes) is calculated by + * multiplying the number of blocks used to hold + * i-nodes by the number of i-nodes in a block. + */ + nfiles = sblock.s_isize * INOPB; + + /* + * Save the name of the file system. + */ + filsys = sblock.s_fname; +} + +/* + * getinodes--read in the i-node structures from the device + * referred to by fd. + */ +getinodes(fd) +int fd; +{ + register ino_t ino; + register daddr_t iblk; + struct dinode *malloc(); + + /* + * Allocate space for them all. + */ + dinode = malloc(nfiles * sizeof(struct dinode)); + + if (dinode == NULL) { + fprintf(stderr, "%s: out of memory.\n", pname); + exit(1); + } + + /* + * We read in i-nodes a disk block-full at a time. + * The INOPB constant is the number of i-nodes in + * a block. + */ + for (ino = 0; ino < nfiles; ino += INOPB) { + /* + * The i-node's disk block number is given by + * the itod macro. + */ + iblk = itod(ino); + + /* + * Read in this block of i-nodes. + */ + bread(fd, iblk, &dinode[ino], BSIZE); + } +} + +/* + * bread--read cnt bytes from fd into buf, starting at + * address bno. + */ +bread(fd, bno, buf, cnt) +daddr_t bno; +char *buf; +int cnt; +{ + int n; + + /* + * Seek to the proper block. The shifting by BSHIFT + * converts the block number to a byte address. + */ + lseek(fd, (long) (bno << BSHIFT), 0); + + /* + * Read in the data. + */ + if ((n = read(fd, buf, cnt)) != cnt) { + perror(filsys); + exit(1); + } +} + +/* + * printusage--print out the disk usage in blocks. + */ +printusage() +{ + register int i; + struct passwd *pwd; + struct passwd *getpwuid(); + + printf("%s (%s):\n", device, filsys); + printf(" Blocks \t User\n"); + + for (i = 0; i < MAXUID; i++) { + if (blocks[i] == 0) + continue; + + /* + * Look up the login name, and use it if + * we find it. + */ + if ((pwd = getpwuid(i)) != NULL) + printf("%8d\t%s\n", blocks[i], pwd->pw_name); + else + printf("%8d\t#%d\n", blocks[i], i); + } +} + diff --git a/reference/C/CONTRIB/OR_USING_C/13.2.c b/reference/C/CONTRIB/OR_USING_C/13.2.c new file mode 100644 index 0000000..023041a --- /dev/null +++ b/reference/C/CONTRIB/OR_USING_C/13.2.c @@ -0,0 +1,267 @@ +/* + * Reads the i-node structures from a raw disk device and + * then sums up the disk usage for each user. Prints out + * the number of blocks each user is using. + * + * If you are on a Sun workstation or other system using Sun's + * Network File System (NFS), be sure to define the constant + * NFS so that the proper files get included. + */ +#ifdef sun +#define NFS 1 +#endif +#ifdef NFS +#include +#include +#include +#include +#include +#include +#include +#include +#else +#include +#include +#include +#include +#include +#include +#endif +/* + * Maximum user id. + */ +#ifndef MAXUID +#define MAXUID 32768 +#endif + +#define sblock sb_un.u_sblock + +/* + * The super block. We allow enough room for + * a complete disk block. + */ +union { + struct fs u_sblock; + char dummy[SBSIZE]; +} sb_un; + +int nfiles; /* number of files in file system */ + +char *pname; /* program name (argv[0]) */ +char *device; /* name of the disk device given */ +char *filsys; /* name of the file system on device */ + +size_t blocks[MAXUID]; /* count of blocks used */ +struct dinode *dinode; /* will hold all the i-node structures */ + +main(argc, argv) +int argc; +char **argv; +{ + int i, fd; + register ino_t ino; + register struct dinode *di; + + /* + * Save the program name and check our arguments. + */ + pname = *argv; + + if (argc != 2) { + fprintf(stderr, "Usage: %s raw-disk-device\n", pname); + exit(1); + } + + /* + * Open the device for reading. + */ + device = *++argv; + + if ((fd = open(device, O_RDONLY)) < 0) { + perror(device); + exit(1); + } + + /* + * Get the super-block from the device. + */ + getsblock(fd); + + /* + * Get the i-node structures from the device. + */ + getinodes(fd); + close(fd); + + /* + * Zero the block counts. + */ + for (i = 0; i < MAXUID; i++) + blocks[i] = 0; + + /* + * Add up the number of blocks being used by + * each user id. + */ + for (ino = 0; ino < nfiles; ino++) { + /* + * ROOTINO is the first i-node; skip any + * before it. + */ + if (ino < ROOTINO) + continue; + + di = &dinode[ino]; + + /* + * If this is zero, the i-node is free (not + * in use). + */ + if ((di->di_mode & IFMT) == 0) + continue; + + /* + * Count the number of blocks being used by + * this file. + */ + blocks[di->di_uid] += di->di_blocks; + } + + /* + * Print out what we added up. + */ + printusage(); + exit(0); +} + +/* + * getsblock--get the super-block from the device + * referred to by fd. + */ +getsblock(fd) +int fd; +{ + /* + * Make sure the disk information is current. + * This causes all disk writes to be scheduled. + */ + sync(); + + /* + * Read in the super-block. It is stored at file + * system block number SBLOCK. + */ + bread(fd, SBLOCK, &sblock, SBSIZE); + + /* + * The number of files (i-nodes) is calculated by + * multiplying the number of i-nodes per cylinder + * group by the number of cylinder groups. + */ + nfiles = sblock.fs_ipg * sblock.fs_ncg; + + /* + * Save the name of the file system. + */ + filsys = sblock.fs_fsmnt; +} + +/* + * getinodes--read in the i-node structures from the device + * referred to by fd. + */ +getinodes(fd) +int fd; +{ + register ino_t ino; + register daddr_t iblk; + struct dinode *malloc(); + + /* + * Allocate space for them all. + */ + dinode = malloc(nfiles * sizeof(struct dinode)); + + if (dinode == NULL) { + fprintf(stderr, "%s: out of memory.\n", pname); + exit(1); + } + + /* + * We read in i-nodes a disk block-full at a time. + * The INOPB macro returns the number of i-nodes + * in a block; it uses the super-block to determine + * the file system block size. + */ + for (ino = 0; ino < nfiles; ino += INOPB(&sblock)) { + /* + * The i-node file system block number is given by + * the itod macro. The disk block number is computed + * from the file system block number by the fsbtodb macro. + */ + + iblk = fsbtodb(&sblock, itod(&sblock, ino)); + + /* + * Read in this block of i-nodes. + */ + bread(fd, iblk, &dinode[ino], sblock.fs_bsize); + } +} + +/* + * bread-read cnt bytes form fd into buf, starting at + * address bno. + */ +bread(fd, bno, buf, cnt) +daddr_t bno; +char *buf; +int cnt; +{ + int n; + + /* + * Seek to the proper block. The dtob macro converts + * the block number to a byte address. + */ + lseek(fd, (long) dtob(bno), L_SET); + + /* + * Round cnt up to a multiple of the device block size. + */ + cnt = roundup(cnt, DEV_BSIZE); + + /* + * Read in the data. + */ + if ((n = read(fd, buf, cnt)) != cnt) { + perror(filsys); + exit(1); + } +} + +/* + * printusage-print out the disk usage in blocks. + */ +printusage() +{ + register int i; + struct passwd *pwd; + + printf("%s (%s):\n", device, filsys); + printf(" Blocks \\t User\n"); + + for (i=0; i < MAXUID; i++) { + if (blocks[i] == 0) + continue; + + /* + * Look up the login name, and use it if we find it. + */ + if ((pwd = getpwuid(i)) != NULL) + printf("%8d\\t%s\n", blocks[i], pwd->pw_name); + else + printf("%8d\\t#%d\n", blocks[i], i); + } +} + diff --git a/reference/C/CONTRIB/OR_USING_C/13.3.c b/reference/C/CONTRIB/OR_USING_C/13.3.c new file mode 100644 index 0000000..a0dc4b1 --- /dev/null +++ b/reference/C/CONTRIB/OR_USING_C/13.3.c @@ -0,0 +1,118 @@ + +#include +#include +#include +#include +#include + +#define sblock sb_un.u_sblock + +/* + * The super block. We allow enough room for + * a complete disk block. + */ +union { + struct fs u_sblock; + char dummy[SBSIZE]; +} sb_un; + +read_blocks(dp) +struct dinode *dp; +{ + int count; + register int i, n; + char dblock[MAXBSIZE]; + + count = dp->di_size; + + /* + * For each direct block in the file (NDADDR indicates + * the number of direct addresses stored)... + */ + for (i = 0; (i < NDADDR) && (count > 0); i++) { + /* + * Read in the block from disk. Read in count + * bytes or a disk block, whichever is less. + */ + bread(fsbtodb(&sblock, dp->di_db[i]), dblock, + n = min(count, sblock.fs_bsize)); + count -= n; + + /* process data block ... */ + + } + + /* + * Now start reading the indirect blocks. NIADDR is + * the number of indirect addresses. Recall that + * the first indirect address is singly indirect, + * the second is doubly indirect, an so on. + */ + for (i = 0; (i < NIADDR) && (count > 0); i++) + read_indirect (dp->di_ib[i], i, &count); +} + +/* + * read_indirect--read the indirect blocks of the file. The + * level argument indicates our level of indirection; 0 is + * singly indirect, 1 is doubly indirect, and so on. + */ +read_indirect (blkno, level, count) +ino_t blkno; +int *count; +int level; +{ + register int i, n; + char dblock[MAXBSIZE]; + daddr_t idblk[MAXBSIZE / sizeof(daddr_t)]; + + /* + * Read in the block from disk. + */ + if (blkno) + bread(fsbtodb(&sblock, blkno), idblk, sblock.fs_bsize); + else + bzero(idblk, sblock.fs_bsize); + + /* + * If level is zero, then this block contains disk block + * addresses, since blkno was a singly indirect address. + * If level is non-zero, then this block contains addresses + * of more indirect blocks. + */ + if (level <= 0) { + /* + * For each disk block (the NINDIR macro returns + * the number of indirect addresses in a block)... + */ + for (i = 0; (i < NINDIR(&sblock)) && (*count > 0); i++) { + /* + * Read in the block from disk. + */ + bread(fsbtodb(&sblock, idblk[i]), dblock, + n = min(*count, sblock.fs_bsize)); + *count -= n; + + /* process data block ... */ + } + + /* + * Done processing. + */ + return; + } + + /* + * Decrement the level we're at. + */ + level--; + + /* + * Handle the next level of indirection by calling + * ourselves recursively with each address in this + * block. + */ + for (i = 0; i < NINDIR(&sblock); i++) + read_indirect(idblk[i], level, count); +} + diff --git a/reference/C/CONTRIB/OR_USING_C/14.1.c b/reference/C/CONTRIB/OR_USING_C/14.1.c new file mode 100644 index 0000000..4ba5035 --- /dev/null +++ b/reference/C/CONTRIB/OR_USING_C/14.1.c @@ -0,0 +1,29 @@ +#include +#include +#include + +/* + * setlim--set the resource limit lim to the value val. + */ +setlim(lim, val) +int lim, val; +{ + struct rlimit rlim; + + /* + * First get the current limits so we + * will know the maximum value. + */ + getrlimit(lim, &rlim); + + /* + * Now change the current limit. + */ + rlim.rlim_cur = val; + + /* + * Now set the new limit. + */ + return(setrlimit(lim, &rlim)); +} + diff --git a/reference/C/CONTRIB/OR_USING_C/14.2.c b/reference/C/CONTRIB/OR_USING_C/14.2.c new file mode 100644 index 0000000..07418aa --- /dev/null +++ b/reference/C/CONTRIB/OR_USING_C/14.2.c @@ -0,0 +1,75 @@ +#include + +#define NSTRS 10 /* number of strings */ +#define STRLEN 16 /* length of each string */ + +char strs[NSTRS][STRLEN]; /* array of strings */ + +main() +{ + int i; + extern int compare1(), compare2(); + + /* + * Prompt the user for NSTRS strings. + */ + for (i = 0; i < NSTRS; i++) { + printf("Enter string #%d: ", i); + gets(strs[i]); + } + + /* + * Sort the strings into ascending order. There + * are NSTRS array elements, each one is STRLEN + * characters long. Note we give the size of + * the array element, not the length of the + * string in it. + */ + qsort(strs, NSTRS, STRLEN, compare1); + + /* + * Print the strings. + */ + printf("\nSorted in ascending order:\n"); + + for (i = 0; i < NSTRS; i++) + printf("\t%s\n", strs[i]); + + /* + * Now sort the strings in descending order. + */ + qsort(strs, NSTRS, STRLEN, compare2); + + printf("\nSorted in descending order:\n"); + + for (i = 0; i < NSTRS; i++) + printf("\t%s\n", strs[i]); + + exit(0); +} + +/* + * compare1--compare a and b, and return less than, + * greater than, or equal to zero. Since + * we are comparing character strings, we + * can just use strcmp to do the work for us. + */ +compare1(a, b) +char *a, *b; +{ + return(strcmp(a, b)); +} + +/* + * compare2--this compares a and b, but is used for + * sorting in the opposite order. Thus it + * returns the opposite of strcmp. We can + * simulate this by simply reversing the + * arguments when we call strcmp. + */ +compare2(a, b) +char *a, *b; +{ + return(strcmp(b, a)); +} + diff --git a/reference/C/CONTRIB/OR_USING_C/HEADER.html b/reference/C/CONTRIB/OR_USING_C/HEADER.html new file mode 100644 index 0000000..c09967d --- /dev/null +++ b/reference/C/CONTRIB/OR_USING_C/HEADER.html @@ -0,0 +1,4 @@ +

Using C - O'Reilly

+Reprinted with permission from 'Using C on the UNIX System' copyright 1989 +O'Reilly and Associates, Inc. For +orders and information, call 1-800-988-9938. diff --git a/reference/C/CONTRIB/OR_USING_C/Makefile.am b/reference/C/CONTRIB/OR_USING_C/Makefile.am new file mode 100644 index 0000000..ad81f7d --- /dev/null +++ b/reference/C/CONTRIB/OR_USING_C/Makefile.am @@ -0,0 +1,5 @@ +EXTRA_DIST = $(wildcard *.html) $(wildcard *.c) $(wildcard *.h) +docs_DATA = $(EXTRA_DIST) + +docsdir = $(kde_htmldir)/en/kdevelop/$(subdir) + diff --git a/reference/C/CONTRIB/OR_USING_C/Makefile.in b/reference/C/CONTRIB/OR_USING_C/Makefile.in new file mode 100644 index 0000000..c941512 --- /dev/null +++ b/reference/C/CONTRIB/OR_USING_C/Makefile.in @@ -0,0 +1,410 @@ +# KDE tags expanded automatically by am_edit - $Revision: 1.2 $ +# Makefile.in generated automatically by automake 1.5 from Makefile.am. + +# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +# Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = ../../../.. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_HEADER = $(INSTALL_DATA) +transform = @program_transform_name@ +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_alias = @build_alias@ +build_triplet = @build@ +host_alias = @host_alias@ +host_triplet = @host@ +target_alias = @target_alias@ +target_triplet = @target@ +AMTAR = @AMTAR@ +ARTSCCONFIG = @ARTSCCONFIG@ +AS = @AS@ +AUTODIRS = @AUTODIRS@ +AWK = @AWK@ +CC = @CC@ +CONF_FILES = @CONF_FILES@ +CPP = @CPP@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +DCOPIDL = @DCOPIDL@ +DCOPIDL2CPP = @DCOPIDL2CPP@ +DCOP_DEPENDENCIES = @DCOP_DEPENDENCIES@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DPMSINC = @DPMSINC@ +DPMSLIB = @DPMSLIB@ +EXEEXT = @EXEEXT@ +GCJ = @GCJ@ +GCJFLAGS = @GCJFLAGS@ +GLINC = @GLINC@ +GLLIB = @GLLIB@ +GMSGFMT = @GMSGFMT@ +IDL = @IDL@ +IDL_DEPENDENCIES = @IDL_DEPENDENCIES@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +JAR = @JAR@ +JAVAC = @JAVAC@ +JAVAH = @JAVAH@ +JVMLIBS = @JVMLIBS@ +KDECONFIG = @KDECONFIG@ +KDE_CXXFLAGS = @KDE_CXXFLAGS@ +KDE_EXTRA_RPATH = @KDE_EXTRA_RPATH@ +KDE_INCLUDES = @KDE_INCLUDES@ +KDE_LDFLAGS = @KDE_LDFLAGS@ +KDE_PLUGIN = @KDE_PLUGIN@ +KDE_RPATH = @KDE_RPATH@ +KDE_USE_CLOSURE_FALSE = @KDE_USE_CLOSURE_FALSE@ +KDE_USE_CLOSURE_TRUE = @KDE_USE_CLOSURE_TRUE@ +KDE_USE_FINAL_FALSE = @KDE_USE_FINAL_FALSE@ +KDE_USE_FINAL_TRUE = @KDE_USE_FINAL_TRUE@ +KDE_XSL_STYLESHEET = @KDE_XSL_STYLESHEET@ +LIBCOMPAT = @LIBCOMPAT@ +LIBCRYPT = @LIBCRYPT@ +LIBDL = @LIBDL@ +LIBGEN = @LIBGEN@ +LIBJPEG = @LIBJPEG@ +LIBMICO = @LIBMICO@ +LIBOBJS = @LIBOBJS@ +LIBPNG = @LIBPNG@ +LIBPTHREAD = @LIBPTHREAD@ +LIBPYTHON = @LIBPYTHON@ +LIBQIMGIO = @LIBQIMGIO@ +LIBRESOLV = @LIBRESOLV@ +LIBSHADOW = @LIBSHADOW@ +LIBSM = @LIBSM@ +LIBSOCKET = @LIBSOCKET@ +LIBTIFF = @LIBTIFF@ +LIBTOOL = @LIBTOOL@ +LIBUCB = @LIBUCB@ +LIBUTIL = @LIBUTIL@ +LIBXINERAMA = @LIBXINERAMA@ +LIBZ = @LIBZ@ +LIB_KAB = @LIB_KAB@ +LIB_KDECORE = @LIB_KDECORE@ +LIB_KDEUI = @LIB_KDEUI@ +LIB_KFILE = @LIB_KFILE@ +LIB_KFM = @LIB_KFM@ +LIB_KFORMULA = @LIB_KFORMULA@ +LIB_KHTML = @LIB_KHTML@ +LIB_KIMGIO = @LIB_KIMGIO@ +LIB_KIO = @LIB_KIO@ +LIB_KPARTS = @LIB_KPARTS@ +LIB_KSPELL = @LIB_KSPELL@ +LIB_KSYCOCA = @LIB_KSYCOCA@ +LIB_KWRITE = @LIB_KWRITE@ +LIB_QT = @LIB_QT@ +LIB_SMB = @LIB_SMB@ +LIB_X11 = @LIB_X11@ +LN_S = @LN_S@ +MCOPIDL = @MCOPIDL@ +MEINPROC = @MEINPROC@ +MICO_INCLUDES = @MICO_INCLUDES@ +MICO_LDFLAGS = @MICO_LDFLAGS@ +MOC = @MOC@ +MSGFMT = @MSGFMT@ +NOOPT_CXXFLAGS = @NOOPT_CXXFLAGS@ +NOREPO = @NOREPO@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PAMLIBS = @PAMLIBS@ +PASSWDLIBS = @PASSWDLIBS@ +PYTHONINC = @PYTHONINC@ +PYTHONLIB = @PYTHONLIB@ +PYTHONMODDIR = @PYTHONMODDIR@ +QT_INCLUDES = @QT_INCLUDES@ +QT_LDFLAGS = @QT_LDFLAGS@ +RANLIB = @RANLIB@ +REPO = @REPO@ +SETUIDFLAGS = @SETUIDFLAGS@ +STRIP = @STRIP@ +TOPSUBDIRS = @TOPSUBDIRS@ +UIC = @UIC@ +UIC_TR = @UIC_TR@ +USER_INCLUDES = @USER_INCLUDES@ +USER_LDFLAGS = @USER_LDFLAGS@ +USE_EXCEPTIONS = @USE_EXCEPTIONS@ +USE_RTTI = @USE_RTTI@ +USE_THREADS = @USE_THREADS@ +VERSION = @VERSION@ +XGETTEXT = @XGETTEXT@ +XPMINC = @XPMINC@ +XPMLIB = @XPMLIB@ +X_EXTRA_LIBS = @X_EXTRA_LIBS@ +X_INCLUDES = @X_INCLUDES@ +X_LDFLAGS = @X_LDFLAGS@ +X_PRE_LIBS = @X_PRE_LIBS@ +all_includes = @all_includes@ +all_libraries = @all_libraries@ +am__include = @am__include@ +am__quote = @am__quote@ +idldir = @idldir@ +install_sh = @install_sh@ +jni_includes = @jni_includes@ +kde_appsdir = @kde_appsdir@ +kde_bindir = @kde_bindir@ +kde_confdir = @kde_confdir@ +kde_datadir = @kde_datadir@ +kde_htmldir = @kde_htmldir@ +kde_icondir = @kde_icondir@ +kde_includes = @kde_includes@ +kde_libraries = @kde_libraries@ +kde_libs_htmldir = @kde_libs_htmldir@ +kde_libs_prefix = @kde_libs_prefix@ +kde_locale = @kde_locale@ +kde_mimedir = @kde_mimedir@ +kde_moduledir = @kde_moduledir@ +kde_qtver = @kde_qtver@ +kde_servicesdir = @kde_servicesdir@ +kde_servicetypesdir = @kde_servicetypesdir@ +kde_sounddir = @kde_sounddir@ +kde_templatesdir = @kde_templatesdir@ +kde_wallpaperdir = @kde_wallpaperdir@ +micodir = @micodir@ +qt_includes = @qt_includes@ +qt_libraries = @qt_libraries@ +x_includes = @x_includes@ +x_libraries = @x_libraries@ + +EXTRA_DIST = $(wildcard *.html) $(wildcard *.c) $(wildcard *.h) +docs_DATA = $(EXTRA_DIST) + +docsdir = $(kde_htmldir)/en/kdevelop/$(subdir) +subdir = reference/C/CONTRIB/OR_USING_C +mkinstalldirs = $(SHELL) $(top_srcdir)/admin/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +DIST_SOURCES = +DATA = $(docs_DATA) + +DIST_COMMON = Makefile.am Makefile.in +#>- all: all-am +#>+ 1 +all: docs-am all-am + +.SUFFIXES: + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) +#>- cd $(top_srcdir) && \ +#>- $(AUTOMAKE) --gnu reference/C/CONTRIB/OR_USING_C/Makefile +#>+ 3 + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu reference/C/CONTRIB/OR_USING_C/Makefile + cd $(top_srcdir) && perl admin/am_edit reference/C/CONTRIB/OR_USING_C/Makefile.in +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) && \ + CONFIG_HEADERS= CONFIG_LINKS= \ + CONFIG_FILES=$(subdir)/$@ $(SHELL) ./config.status +uninstall-info-am: +install-docsDATA: $(docs_DATA) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(docsdir) + @list='$(docs_DATA)'; for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + f="`echo $$p | sed -e 's|^.*/||'`"; \ + echo " $(INSTALL_DATA) $$d$$p $(DESTDIR)$(docsdir)/$$f"; \ + $(INSTALL_DATA) $$d$$p $(DESTDIR)$(docsdir)/$$f; \ + done + +uninstall-docsDATA: + @$(NORMAL_UNINSTALL) + @list='$(docs_DATA)'; for p in $$list; do \ + f="`echo $$p | sed -e 's|^.*/||'`"; \ + echo " rm -f $(DESTDIR)$(docsdir)/$$f"; \ + rm -f $(DESTDIR)$(docsdir)/$$f; \ + done +tags: TAGS +TAGS: + + +#>- DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +#>+ 4 +KDE_DIST=05.2.c a.4.c 10.2.c 03.1.c 09.2.c 02.3.c 08.4.c 12.2.c 11.4.c 05.1.c 04.3.c b.1.c a.3.c 10.h 14.2.c 07.1.c d.1.c 10.1.c a.7.c 09.1.c 02.2.c 08.3.c 12.1.c 11.3.c 10.5.c 04.2.c a.2.c 14.1.c 08.7.c 13.3.c 11.7.c nap.c a.6.c 02.1.c 08.2.c 11.2.c 10.4.c 04.1.c a.1.c 09.4.c 02.5.c 08.6.c 13.2.c 11.6.c 06.1.c 05.3.c c.1.c a.5.c HEADER.html 08.1.c e.1.c 11.1.c 10.3.c dircom.c 03.2.c 09.3.c 02.4.c 08.5.c 13.1.c 12.3.c 11.5.c + +DISTFILES= $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) $(KDE_DIST) + + +top_distdir = ../../../.. +distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + if test -f $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + $(mkinstalldirs) "$(distdir)/$$dir"; \ + fi; \ + if test -d $$d/$$file; then \ + cp -pR $$d/$$file $(distdir) \ + || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(DATA) + +installdirs: + $(mkinstalldirs) $(DESTDIR)$(docsdir) + +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) stamp-h stamp-h[0-9]* + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +#>- clean: clean-am +#>+ 1 +clean: kde-rpo-clean clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + +distclean-am: clean-am distclean-generic distclean-libtool + +dvi: dvi-am + +dvi-am: + +info: info-am + +info-am: + +install-data-am: install-docsDATA + +install-exec-am: + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +uninstall-am: uninstall-docsDATA uninstall-info-am + +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + distclean distclean-generic distclean-libtool distdir dvi \ + dvi-am info info-am install install-am install-data \ + install-data-am install-docsDATA install-exec install-exec-am \ + install-info install-info-am install-man install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool uninstall uninstall-am uninstall-docsDATA \ + uninstall-info-am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: + +#>+ 2 +docs-am: + +#>+ 6 +force-reedit: + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu reference/C/CONTRIB/OR_USING_C/Makefile + cd $(top_srcdir) && perl admin/am_edit reference/C/CONTRIB/OR_USING_C/Makefile.in + + +#>+ 2 +final: + $(MAKE) all-am +#>+ 2 +final-install: + $(MAKE) install-am +#>+ 2 +no-final: + $(MAKE) all-am +#>+ 2 +no-final-install: + $(MAKE) install-am +#>+ 3 +cvs-clean: + $(MAKE) -f $(top_srcdir)/admin/Makefile.common cvs-clean + +#>+ 3 +kde-rpo-clean: + -rm -f *.rpo diff --git a/reference/C/CONTRIB/OR_USING_C/a.1.c b/reference/C/CONTRIB/OR_USING_C/a.1.c new file mode 100644 index 0000000..d1d2749 --- /dev/null +++ b/reference/C/CONTRIB/OR_USING_C/a.1.c @@ -0,0 +1,4 @@ +hello_() /* note underscore */ +{ + printf("Hello, world.\n"); +} diff --git a/reference/C/CONTRIB/OR_USING_C/a.2.c b/reference/C/CONTRIB/OR_USING_C/a.2.c new file mode 100644 index 0000000..2f6782e --- /dev/null +++ b/reference/C/CONTRIB/OR_USING_C/a.2.c @@ -0,0 +1,6 @@ +extern hello(); + +main() +{ + hello_(); +} diff --git a/reference/C/CONTRIB/OR_USING_C/a.3.c b/reference/C/CONTRIB/OR_USING_C/a.3.c new file mode 100644 index 0000000..d2ce1f6 --- /dev/null +++ b/reference/C/CONTRIB/OR_USING_C/a.3.c @@ -0,0 +1,12 @@ +main() +{ + extern long y_(); + long i; + + i = y_(); +} + +long x_() +{ + return(5L); +} diff --git a/reference/C/CONTRIB/OR_USING_C/a.4.c b/reference/C/CONTRIB/OR_USING_C/a.4.c new file mode 100644 index 0000000..03d0639 --- /dev/null +++ b/reference/C/CONTRIB/OR_USING_C/a.4.c @@ -0,0 +1,18 @@ +typedef struct { + float r, i; +} complex; + +main() +{ + extern complex y_(); + complex i; + + y_(&i); +} + +x_(c) +complex *c; +{ + c->r = 1.0; + c->i = 2.0; +} diff --git a/reference/C/CONTRIB/OR_USING_C/a.5.c b/reference/C/CONTRIB/OR_USING_C/a.5.c new file mode 100644 index 0000000..ff298c7 --- /dev/null +++ b/reference/C/CONTRIB/OR_USING_C/a.5.c @@ -0,0 +1,29 @@ +main() +{ + extern char *y_(); + char s[15]; + + y_(s, 15L); +} + +x_(s, len) +char *s; +long len; +{ + s[0] = 'a'; + s[1] = 'b'; + s[2] = 'c'; + s[3] = 'd'; + s[4] = 'e'; + s[5] = 'f'; + s[6] = 'g'; + s[7] = 'h'; + s[8] = 'i'; + s[9] = 'j'; + s[10] = 'k'; + s[11] = 'l'; + s[12] = 'm'; + s[13] = 'n'; + s[14] = 'o'; +} + diff --git a/reference/C/CONTRIB/OR_USING_C/a.6.c b/reference/C/CONTRIB/OR_USING_C/a.6.c new file mode 100644 index 0000000..5b0be32 --- /dev/null +++ b/reference/C/CONTRIB/OR_USING_C/a.6.c @@ -0,0 +1,19 @@ +main() +{ + extern y_(); + long a, b, c; + + a = 4; + b = 5; + c = 6; + + y_(&a, &b, &c); +} + +x_(u, v, w) +long *u, *v, *w; +{ + *u *= 2; + *v *= 3; + *w *= 4; +} diff --git a/reference/C/CONTRIB/OR_USING_C/a.7.c b/reference/C/CONTRIB/OR_USING_C/a.7.c new file mode 100644 index 0000000..f5e0cc9 --- /dev/null +++ b/reference/C/CONTRIB/OR_USING_C/a.7.c @@ -0,0 +1,16 @@ +main() +{ + extern char *y_(); + char *i; + + i = "hi there"; + y_(i, 8L); +} + +x_(s, len) +char *s; +long len; +{ + write(1, s, len); +} + diff --git a/reference/C/CONTRIB/OR_USING_C/b.1.c b/reference/C/CONTRIB/OR_USING_C/b.1.c new file mode 100644 index 0000000..422b975 --- /dev/null +++ b/reference/C/CONTRIB/OR_USING_C/b.1.c @@ -0,0 +1,176 @@ +#include +#include +#include +#include +#include + +ptyopen(cmd, ifp, ofp) +char *cmd; +FILE **ifp, **ofp; +{ + int i; + char *args[16]; + register int tty; + long ldisc, lmode; + register char *s, *t; + struct sgttyb sgttyb; + struct tchars tchars; + struct ltchars ltchars; + char ttybuf[16], ptybuf[16]; + + /* + * Split up the arguments in the command + * into an argv-like structure. + */ + i = 0; + s = cmd; + + while (*s) { + /* + * Skip white space. + */ + while ((*s == ' ') || (*s == '\t')) + *s++ = NULL; + + args[i++] = s; + + /* + * Skip over this word to next white space. + */ + while ((*s != NULL) && (*s != ' ') && (*s != '\t')) + s++; + } + args[i] = NULL; + /* + * Get a pseudo-tty. We do this by cycling through all + * the possible names. The operating system will not + * allow us to open a master which is already in use, + * so we simply go until the open succeeds. + */ + for (s = "pqrs"; *s != NULL; s++) { + for (t = "0123456789abcdef"; *t != NULL; t++) { + sprintf(ptybuf, "/dev/pty%c%c", *s, *t); + if ((tty = open(ptybuf, O_RDWR)) >= 0) + goto out; + } + } +out: + /* + * If s and t are NULL, we ran out of pseudo ttys + * before we found one we can use. + */ + if ((*s == NULL) && (*t == NULL)) + return(-1); + /* + * Change "ptyXX" (master) to "ttyXX" (slave). + */ + strcpy(ttybuf, ptybuf); + ttybuf[5] = 't'; + /* + * Get the modes of the current terminal. We + * will duplicate these on the pseudo terminal. + */ + ioctl(0, TIOCGETD, &ldisc); + ioctl(0, TIOCLGET, &lmode); + ioctl(0, TIOCGETP, &sgttyb); + ioctl(0, TIOCGETC, &tchars); + ioctl(0, TIOCGLTC, <chars); + /* + * Fork a child process. + */ + if ((i = fork()) < 0) { + close(tty); + return(-1); + } + + /* + * In the child... + */ + if (i == 0) { + /* + * Close all open files. + */ + for (i = 0; i < NOFILE; i++) + close(i); + + /* + * Clear the controlling tty. This means + * that we will not have a controlling + * tty until we open another terminal + * device. + */ + if ((i = open("/dev/tty", O_RDWR)) >= 0) { + ioctl(i, TIOCNOTTY, 0); + close(i); + } + + /* + * Make our controlling tty the pseudo tty. + * This happens because we cleared our + * original controlling terminal above. + */ + i = open(ttybuf, O_RDWR); + + /* + * Set stdin, stdout, and stderr to be the + * pseudo terminal. + */ + dup2(i, 0); + dup2(i, 1); + dup2(i, 2); + + /* + * Set the pseudo terminal's tty modes to + * those of the original terminal. We + * turn off ECHO and CBREAK modes, since + * we don't want characters "typed" to be + * printed. + */ + sgttyb.sg_flags &= ~ECHO; + sgttyb.sg_flags &= ~CRMOD; + + ioctl(0, TIOCSETD, &ldisc); + ioctl(0, TIOCLGET, &lmode); + ioctl(0, TIOCSETP, &sgttyb); + ioctl(0, TIOCSETC, &tchars); + ioctl(0, TIOCSLTC, <chars); + + /* + * Set the process group of the process + * to be the process group of the + * terminal. + */ + ioctl(0, TIOCGPGRP, &i); + setpgrp(0, i); + + /* + * Now change the process group of the + * terminal and process to be the + * process id; this takes them out + * of the calling process's process + * group. + */ + i = getpid(); + + ioctl(0, TIOCSPGRP, &i); + setpgrp(0, i); + + /* + * Execute the program. + */ + execv(*args, args); + + exit(1); + } + + /* + * Set up the input and output file pointers + * so that they can write and read the pseudo + * terminal. + */ + *ifp = fdopen(tty, "w"); + *ofp = fdopen(tty, "r"); + + return(0); +} + diff --git a/reference/C/CONTRIB/OR_USING_C/c.1.c b/reference/C/CONTRIB/OR_USING_C/c.1.c new file mode 100644 index 0000000..257f3c8 --- /dev/null +++ b/reference/C/CONTRIB/OR_USING_C/c.1.c @@ -0,0 +1,96 @@ +#include +#include +#include +#include +#include + +/* + * We declare an array of nlist structures, + * and initialize them to the names of the + * variables we want. The last entry is + * to terminate the list. + */ +struct nlist nl[] = { +#define X_BOOTTIME 0 + { "_boottime" }, +#define X_AVENRUN 1 + { "_avenrun" }, + { 0 } +}; + +main() +{ + int kmem; + char *ctime(); + struct timeval boottime; + + /* + * _avenrun is an array of three numbers. + * Most machines use floating point; Sun + * workstations use long integers. + */ +#ifdef sun + long avenrun[3]; +#else + double avenrun[3]; +#endif + + /* + * Open kernel memory. + */ + if ((kmem = open("/dev/kmem", O_RDONLY)) < 0) { + perror("/dev/kmem"); + exit(1); + } + + /* + * Read the kernel namelist. If nl[0].n_type is + * 0 after this, then the call to nlist() failed. + */ + if ((nlist("/vmunix", nl) < 0) || (nl[0].n_type == 0)) { + fprintf(stderr, "/vmunix: no namelist\n"); + exit(1); + } + + /* + * Read the _boottime variable. We do this by + * seeking through memory to the address found + * by nlist, and then reading. + */ + lseek(kmem, (long) nl[X_BOOTTIME].n_value, L_SET); + read(kmem, (char *) &boottime, sizeof(boottime)); + /* + * Read the load averages. + */ + lseek(kmem, (long) nl[X_AVENRUN].n_value, L_SET); + read(kmem, (char *) avenrun, sizeof(avenrun)); + + /* + * Now print the system boot time. + */ + printf("System booted at %s\n", ctime(&boottime.tv_sec)); + + /* + * Print the load averages. Sun workstations use + * FSCALE to convert the long integers to floating + * point. The three elements of _avenrun are the + * load average over the past one, five, and ten + * minutes. + */ +#ifdef sun + printf("One minute load average: %.2f\n", + (double) avenrun[0] / FSCALE); + printf("Five minute load average: %.2f\n", + (double) avenrun[1] / FSCALE); + printf("Ten minute load average: %.2f\n", + (double) avenrun[2] / FSCALE); +#else + printf("One minute load average: %.2f\n", avenrun[0]); + printf("Five minute load average: %.2f\n", avenrun[1]); + printf("Ten minute load average: %.2f\n", avenrun[2]); +#endif + + close(kmem); + exit(0); +} + diff --git a/reference/C/CONTRIB/OR_USING_C/d.1.c b/reference/C/CONTRIB/OR_USING_C/d.1.c new file mode 100644 index 0000000..2b2b9ab --- /dev/null +++ b/reference/C/CONTRIB/OR_USING_C/d.1.c @@ -0,0 +1,117 @@ + +/* + * Non-BSD systems only. + */ +#include +#include +#include +#include + +#define DIRSIZE(e) (min(strlen(e->d_name), DIRSIZ)) + +typedef struct { + int d_fd; +} DIR; + +char *malloc(); + +DIR * +opendir(dir) +char *dir; +{ + struct stat stbuf; + DIR *dp = (DIR *) malloc(sizeof *dp); + + if ((dp->d_fd = open(dir, 0)) < 0) + return(0); + + if ((fstat(dp->d_fd, &stbuf) < 0) || + ((stbuf.st_mode & S_IFDIR) == 0)) { + closedir(dp); + return(0); /* this isn't a directory! */ + } + + return(dp); +} + +closedir(dp) +DIR *dp; +{ + (void) close(dp->d_fd); + free((char *) dp); +} + +struct direct * +readdir(dp) +DIR *dp; +{ + static struct direct dir; + + do { + if (read(dp->d_fd, &dir, sizeof(dir)) != sizeof(dir)) + return(0); + } while (dir.d_ino == 0); + + return(&dir); +} + +/* + * Scandir returns the number of entries or -1 if the + * directory cannot be opened or malloc fails. + */ +scandir(dir, nmptr, select, compar) +char *dir; +char ***nmptr; +int (*select)(); +int (*compar)(); +{ + DIR *dirp; + char **array; + char **realloc(); + struct direct *ent; + unsigned int nalloc = 10, nentries = 0; + + if ((dirp = opendir(dir)) == NULL) + return(-1); + + array = (char **) malloc(nalloc * sizeof (char *)); + + if (array == NULL) + return(-1); + + while ((ent = readdir(dirp)) != NULL) { + if (select && ((*select)(ent->d_name) == 0)) + continue; + + if (nentries == nalloc) { + array = realloc(array, (nalloc += 10) * sizeof(char *)); + + if (array == NULL) + return(-1); + } + + array[nentries] = (char *) malloc(DIRSIZE(ent)+1); + strncpy(array[nentries], ent->d_name, DIRSIZE(ent)); + array[nentries][DIRSIZE(ent)] = NULL; + nentries++; + } + + closedir(dirp); + + if ((nentries + 1) != nalloc) + array = realloc(array, ((nentries + 1) * sizeof (char *))); + + if (compar != 0) + qsort(array, nentries, sizeof(char **), compar); + + *nmptr = array; + array[nentries] = 0; /* guaranteed 0 pointer */ + + return(nentries); +} + +alphasort(a, b) +char **a, **b; +{ + return(strcmp(*a, *b)); +} diff --git a/reference/C/CONTRIB/OR_USING_C/dircom.c b/reference/C/CONTRIB/OR_USING_C/dircom.c new file mode 100644 index 0000000..2b2b9ab --- /dev/null +++ b/reference/C/CONTRIB/OR_USING_C/dircom.c @@ -0,0 +1,117 @@ + +/* + * Non-BSD systems only. + */ +#include +#include +#include +#include + +#define DIRSIZE(e) (min(strlen(e->d_name), DIRSIZ)) + +typedef struct { + int d_fd; +} DIR; + +char *malloc(); + +DIR * +opendir(dir) +char *dir; +{ + struct stat stbuf; + DIR *dp = (DIR *) malloc(sizeof *dp); + + if ((dp->d_fd = open(dir, 0)) < 0) + return(0); + + if ((fstat(dp->d_fd, &stbuf) < 0) || + ((stbuf.st_mode & S_IFDIR) == 0)) { + closedir(dp); + return(0); /* this isn't a directory! */ + } + + return(dp); +} + +closedir(dp) +DIR *dp; +{ + (void) close(dp->d_fd); + free((char *) dp); +} + +struct direct * +readdir(dp) +DIR *dp; +{ + static struct direct dir; + + do { + if (read(dp->d_fd, &dir, sizeof(dir)) != sizeof(dir)) + return(0); + } while (dir.d_ino == 0); + + return(&dir); +} + +/* + * Scandir returns the number of entries or -1 if the + * directory cannot be opened or malloc fails. + */ +scandir(dir, nmptr, select, compar) +char *dir; +char ***nmptr; +int (*select)(); +int (*compar)(); +{ + DIR *dirp; + char **array; + char **realloc(); + struct direct *ent; + unsigned int nalloc = 10, nentries = 0; + + if ((dirp = opendir(dir)) == NULL) + return(-1); + + array = (char **) malloc(nalloc * sizeof (char *)); + + if (array == NULL) + return(-1); + + while ((ent = readdir(dirp)) != NULL) { + if (select && ((*select)(ent->d_name) == 0)) + continue; + + if (nentries == nalloc) { + array = realloc(array, (nalloc += 10) * sizeof(char *)); + + if (array == NULL) + return(-1); + } + + array[nentries] = (char *) malloc(DIRSIZE(ent)+1); + strncpy(array[nentries], ent->d_name, DIRSIZE(ent)); + array[nentries][DIRSIZE(ent)] = NULL; + nentries++; + } + + closedir(dirp); + + if ((nentries + 1) != nalloc) + array = realloc(array, ((nentries + 1) * sizeof (char *))); + + if (compar != 0) + qsort(array, nentries, sizeof(char **), compar); + + *nmptr = array; + array[nentries] = 0; /* guaranteed 0 pointer */ + + return(nentries); +} + +alphasort(a, b) +char **a, **b; +{ + return(strcmp(*a, *b)); +} diff --git a/reference/C/CONTRIB/OR_USING_C/e.1.c b/reference/C/CONTRIB/OR_USING_C/e.1.c new file mode 100644 index 0000000..09f4a74 --- /dev/null +++ b/reference/C/CONTRIB/OR_USING_C/e.1.c @@ -0,0 +1,63 @@ +#include +#include + +#define setvec(vec, a) \ + vec.sv_handler = a; \ + vec.sv_mask = vec.sv_flags = 0 + +static int ringring; + +nap(n) +unsigned n; +{ + void napx(); + int omask; + struct sigvec vec, ovec; + struct itimerval itv, oitv; + register struct itimerval *itp = &itv; + + if (n == 0) + return; + timerclear(&itp->it_interval); + timerclear(&itp->it_value); + if (setitimer(ITIMER_REAL, itp, &oitv) < 0) + return; + setvec(ovec, SIG_DFL); + omask = sigblock(sigmask(SIGALRM)); + itp->it_value.tv_sec = n/60; + itp->it_value.tv_usec = (n%60)*1000000/60; + if (timerisset(&oitv.it_value)) { + if (oitv.it_value.tv_sec >= itp->it_value.tv_sec) { + if (oitv.it_value.tv_sec == itp->it_value.tv_sec && + oitv.it_value.tv_usec > itp->it_value.tv_usec) + oitv.it_value.tv_usec -= itp->it_value.tv_usec; + oitv.it_value.tv_sec -= itp->it_value.tv_sec; + } + else { + itp->it_value = oitv.it_value; + /* + * This is a hack, but we must have time to return from + * the setitimer after the alarm or else it will restart. + * And, anyway, sleep never did more than this before. + */ + oitv.it_value.tv_sec = 1; + oitv.it_value.tv_usec = 0; + } + } + setvec(vec, napx); + ringring = 0; + sigvec(SIGALRM, &vec, &ovec); + setitimer(ITIMER_REAL, itp, (struct itimerval *)0); + while (!ringring) + sigpause(omask &~ sigmask(SIGALRM)); + sigvec(SIGALRM, &ovec, (struct sigvec *)0); + setitimer(ITIMER_REAL, &oitv, (struct itimerval *)0); + sigsetmask(omask); +} + +static void +napx() +{ + ringring = 1; +} + diff --git a/reference/C/CONTRIB/OR_USING_C/nap.c b/reference/C/CONTRIB/OR_USING_C/nap.c new file mode 100644 index 0000000..09f4a74 --- /dev/null +++ b/reference/C/CONTRIB/OR_USING_C/nap.c @@ -0,0 +1,63 @@ +#include +#include + +#define setvec(vec, a) \ + vec.sv_handler = a; \ + vec.sv_mask = vec.sv_flags = 0 + +static int ringring; + +nap(n) +unsigned n; +{ + void napx(); + int omask; + struct sigvec vec, ovec; + struct itimerval itv, oitv; + register struct itimerval *itp = &itv; + + if (n == 0) + return; + timerclear(&itp->it_interval); + timerclear(&itp->it_value); + if (setitimer(ITIMER_REAL, itp, &oitv) < 0) + return; + setvec(ovec, SIG_DFL); + omask = sigblock(sigmask(SIGALRM)); + itp->it_value.tv_sec = n/60; + itp->it_value.tv_usec = (n%60)*1000000/60; + if (timerisset(&oitv.it_value)) { + if (oitv.it_value.tv_sec >= itp->it_value.tv_sec) { + if (oitv.it_value.tv_sec == itp->it_value.tv_sec && + oitv.it_value.tv_usec > itp->it_value.tv_usec) + oitv.it_value.tv_usec -= itp->it_value.tv_usec; + oitv.it_value.tv_sec -= itp->it_value.tv_sec; + } + else { + itp->it_value = oitv.it_value; + /* + * This is a hack, but we must have time to return from + * the setitimer after the alarm or else it will restart. + * And, anyway, sleep never did more than this before. + */ + oitv.it_value.tv_sec = 1; + oitv.it_value.tv_usec = 0; + } + } + setvec(vec, napx); + ringring = 0; + sigvec(SIGALRM, &vec, &ovec); + setitimer(ITIMER_REAL, itp, (struct itimerval *)0); + while (!ringring) + sigpause(omask &~ sigmask(SIGALRM)); + sigvec(SIGALRM, &ovec, (struct sigvec *)0); + setitimer(ITIMER_REAL, &oitv, (struct itimerval *)0); + sigsetmask(omask); +} + +static void +napx() +{ + ringring = 1; +} + diff --git a/reference/C/CONTRIB/SAWTELL/Makefile.am b/reference/C/CONTRIB/SAWTELL/Makefile.am new file mode 100644 index 0000000..f4e2289 --- /dev/null +++ b/reference/C/CONTRIB/SAWTELL/Makefile.am @@ -0,0 +1,5 @@ +EXTRA_DIST = $(wildcard *.html) $(wildcard c-lesson.*) +docs_DATA = $(EXTRA_DIST) + +docsdir = $(kde_htmldir)/en/kdevelop/$(subdir) + diff --git a/reference/C/CONTRIB/SAWTELL/Makefile.in b/reference/C/CONTRIB/SAWTELL/Makefile.in new file mode 100644 index 0000000..37813f0 --- /dev/null +++ b/reference/C/CONTRIB/SAWTELL/Makefile.in @@ -0,0 +1,410 @@ +# KDE tags expanded automatically by am_edit - $Revision: 1.2 $ +# Makefile.in generated automatically by automake 1.5 from Makefile.am. + +# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +# Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = ../../../.. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_HEADER = $(INSTALL_DATA) +transform = @program_transform_name@ +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_alias = @build_alias@ +build_triplet = @build@ +host_alias = @host_alias@ +host_triplet = @host@ +target_alias = @target_alias@ +target_triplet = @target@ +AMTAR = @AMTAR@ +ARTSCCONFIG = @ARTSCCONFIG@ +AS = @AS@ +AUTODIRS = @AUTODIRS@ +AWK = @AWK@ +CC = @CC@ +CONF_FILES = @CONF_FILES@ +CPP = @CPP@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +DCOPIDL = @DCOPIDL@ +DCOPIDL2CPP = @DCOPIDL2CPP@ +DCOP_DEPENDENCIES = @DCOP_DEPENDENCIES@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DPMSINC = @DPMSINC@ +DPMSLIB = @DPMSLIB@ +EXEEXT = @EXEEXT@ +GCJ = @GCJ@ +GCJFLAGS = @GCJFLAGS@ +GLINC = @GLINC@ +GLLIB = @GLLIB@ +GMSGFMT = @GMSGFMT@ +IDL = @IDL@ +IDL_DEPENDENCIES = @IDL_DEPENDENCIES@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +JAR = @JAR@ +JAVAC = @JAVAC@ +JAVAH = @JAVAH@ +JVMLIBS = @JVMLIBS@ +KDECONFIG = @KDECONFIG@ +KDE_CXXFLAGS = @KDE_CXXFLAGS@ +KDE_EXTRA_RPATH = @KDE_EXTRA_RPATH@ +KDE_INCLUDES = @KDE_INCLUDES@ +KDE_LDFLAGS = @KDE_LDFLAGS@ +KDE_PLUGIN = @KDE_PLUGIN@ +KDE_RPATH = @KDE_RPATH@ +KDE_USE_CLOSURE_FALSE = @KDE_USE_CLOSURE_FALSE@ +KDE_USE_CLOSURE_TRUE = @KDE_USE_CLOSURE_TRUE@ +KDE_USE_FINAL_FALSE = @KDE_USE_FINAL_FALSE@ +KDE_USE_FINAL_TRUE = @KDE_USE_FINAL_TRUE@ +KDE_XSL_STYLESHEET = @KDE_XSL_STYLESHEET@ +LIBCOMPAT = @LIBCOMPAT@ +LIBCRYPT = @LIBCRYPT@ +LIBDL = @LIBDL@ +LIBGEN = @LIBGEN@ +LIBJPEG = @LIBJPEG@ +LIBMICO = @LIBMICO@ +LIBOBJS = @LIBOBJS@ +LIBPNG = @LIBPNG@ +LIBPTHREAD = @LIBPTHREAD@ +LIBPYTHON = @LIBPYTHON@ +LIBQIMGIO = @LIBQIMGIO@ +LIBRESOLV = @LIBRESOLV@ +LIBSHADOW = @LIBSHADOW@ +LIBSM = @LIBSM@ +LIBSOCKET = @LIBSOCKET@ +LIBTIFF = @LIBTIFF@ +LIBTOOL = @LIBTOOL@ +LIBUCB = @LIBUCB@ +LIBUTIL = @LIBUTIL@ +LIBXINERAMA = @LIBXINERAMA@ +LIBZ = @LIBZ@ +LIB_KAB = @LIB_KAB@ +LIB_KDECORE = @LIB_KDECORE@ +LIB_KDEUI = @LIB_KDEUI@ +LIB_KFILE = @LIB_KFILE@ +LIB_KFM = @LIB_KFM@ +LIB_KFORMULA = @LIB_KFORMULA@ +LIB_KHTML = @LIB_KHTML@ +LIB_KIMGIO = @LIB_KIMGIO@ +LIB_KIO = @LIB_KIO@ +LIB_KPARTS = @LIB_KPARTS@ +LIB_KSPELL = @LIB_KSPELL@ +LIB_KSYCOCA = @LIB_KSYCOCA@ +LIB_KWRITE = @LIB_KWRITE@ +LIB_QT = @LIB_QT@ +LIB_SMB = @LIB_SMB@ +LIB_X11 = @LIB_X11@ +LN_S = @LN_S@ +MCOPIDL = @MCOPIDL@ +MEINPROC = @MEINPROC@ +MICO_INCLUDES = @MICO_INCLUDES@ +MICO_LDFLAGS = @MICO_LDFLAGS@ +MOC = @MOC@ +MSGFMT = @MSGFMT@ +NOOPT_CXXFLAGS = @NOOPT_CXXFLAGS@ +NOREPO = @NOREPO@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PAMLIBS = @PAMLIBS@ +PASSWDLIBS = @PASSWDLIBS@ +PYTHONINC = @PYTHONINC@ +PYTHONLIB = @PYTHONLIB@ +PYTHONMODDIR = @PYTHONMODDIR@ +QT_INCLUDES = @QT_INCLUDES@ +QT_LDFLAGS = @QT_LDFLAGS@ +RANLIB = @RANLIB@ +REPO = @REPO@ +SETUIDFLAGS = @SETUIDFLAGS@ +STRIP = @STRIP@ +TOPSUBDIRS = @TOPSUBDIRS@ +UIC = @UIC@ +UIC_TR = @UIC_TR@ +USER_INCLUDES = @USER_INCLUDES@ +USER_LDFLAGS = @USER_LDFLAGS@ +USE_EXCEPTIONS = @USE_EXCEPTIONS@ +USE_RTTI = @USE_RTTI@ +USE_THREADS = @USE_THREADS@ +VERSION = @VERSION@ +XGETTEXT = @XGETTEXT@ +XPMINC = @XPMINC@ +XPMLIB = @XPMLIB@ +X_EXTRA_LIBS = @X_EXTRA_LIBS@ +X_INCLUDES = @X_INCLUDES@ +X_LDFLAGS = @X_LDFLAGS@ +X_PRE_LIBS = @X_PRE_LIBS@ +all_includes = @all_includes@ +all_libraries = @all_libraries@ +am__include = @am__include@ +am__quote = @am__quote@ +idldir = @idldir@ +install_sh = @install_sh@ +jni_includes = @jni_includes@ +kde_appsdir = @kde_appsdir@ +kde_bindir = @kde_bindir@ +kde_confdir = @kde_confdir@ +kde_datadir = @kde_datadir@ +kde_htmldir = @kde_htmldir@ +kde_icondir = @kde_icondir@ +kde_includes = @kde_includes@ +kde_libraries = @kde_libraries@ +kde_libs_htmldir = @kde_libs_htmldir@ +kde_libs_prefix = @kde_libs_prefix@ +kde_locale = @kde_locale@ +kde_mimedir = @kde_mimedir@ +kde_moduledir = @kde_moduledir@ +kde_qtver = @kde_qtver@ +kde_servicesdir = @kde_servicesdir@ +kde_servicetypesdir = @kde_servicetypesdir@ +kde_sounddir = @kde_sounddir@ +kde_templatesdir = @kde_templatesdir@ +kde_wallpaperdir = @kde_wallpaperdir@ +micodir = @micodir@ +qt_includes = @qt_includes@ +qt_libraries = @qt_libraries@ +x_includes = @x_includes@ +x_libraries = @x_libraries@ + +EXTRA_DIST = $(wildcard *.html) $(wildcard c-lesson.*) +docs_DATA = $(EXTRA_DIST) + +docsdir = $(kde_htmldir)/en/kdevelop/$(subdir) +subdir = reference/C/CONTRIB/SAWTELL +mkinstalldirs = $(SHELL) $(top_srcdir)/admin/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +DIST_SOURCES = +DATA = $(docs_DATA) + +DIST_COMMON = Makefile.am Makefile.in +#>- all: all-am +#>+ 1 +all: docs-am all-am + +.SUFFIXES: + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) +#>- cd $(top_srcdir) && \ +#>- $(AUTOMAKE) --gnu reference/C/CONTRIB/SAWTELL/Makefile +#>+ 3 + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu reference/C/CONTRIB/SAWTELL/Makefile + cd $(top_srcdir) && perl admin/am_edit reference/C/CONTRIB/SAWTELL/Makefile.in +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) && \ + CONFIG_HEADERS= CONFIG_LINKS= \ + CONFIG_FILES=$(subdir)/$@ $(SHELL) ./config.status +uninstall-info-am: +install-docsDATA: $(docs_DATA) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(docsdir) + @list='$(docs_DATA)'; for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + f="`echo $$p | sed -e 's|^.*/||'`"; \ + echo " $(INSTALL_DATA) $$d$$p $(DESTDIR)$(docsdir)/$$f"; \ + $(INSTALL_DATA) $$d$$p $(DESTDIR)$(docsdir)/$$f; \ + done + +uninstall-docsDATA: + @$(NORMAL_UNINSTALL) + @list='$(docs_DATA)'; for p in $$list; do \ + f="`echo $$p | sed -e 's|^.*/||'`"; \ + echo " rm -f $(DESTDIR)$(docsdir)/$$f"; \ + rm -f $(DESTDIR)$(docsdir)/$$f; \ + done +tags: TAGS +TAGS: + + +#>- DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +#>+ 4 +KDE_DIST=intro.html c-lesson.1 c-lesson.2 c-lesson.3 c-lesson.4 c-lesson.5 c-lesson.6 c-lesson.7 c-lesson.8 c-lesson.9 + +DISTFILES= $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) $(KDE_DIST) + + +top_distdir = ../../../.. +distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + if test -f $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + $(mkinstalldirs) "$(distdir)/$$dir"; \ + fi; \ + if test -d $$d/$$file; then \ + cp -pR $$d/$$file $(distdir) \ + || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(DATA) + +installdirs: + $(mkinstalldirs) $(DESTDIR)$(docsdir) + +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) stamp-h stamp-h[0-9]* + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +#>- clean: clean-am +#>+ 1 +clean: kde-rpo-clean clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + +distclean-am: clean-am distclean-generic distclean-libtool + +dvi: dvi-am + +dvi-am: + +info: info-am + +info-am: + +install-data-am: install-docsDATA + +install-exec-am: + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +uninstall-am: uninstall-docsDATA uninstall-info-am + +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + distclean distclean-generic distclean-libtool distdir dvi \ + dvi-am info info-am install install-am install-data \ + install-data-am install-docsDATA install-exec install-exec-am \ + install-info install-info-am install-man install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool uninstall uninstall-am uninstall-docsDATA \ + uninstall-info-am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: + +#>+ 2 +docs-am: + +#>+ 6 +force-reedit: + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu reference/C/CONTRIB/SAWTELL/Makefile + cd $(top_srcdir) && perl admin/am_edit reference/C/CONTRIB/SAWTELL/Makefile.in + + +#>+ 2 +final: + $(MAKE) all-am +#>+ 2 +final-install: + $(MAKE) install-am +#>+ 2 +no-final: + $(MAKE) all-am +#>+ 2 +no-final-install: + $(MAKE) install-am +#>+ 3 +cvs-clean: + $(MAKE) -f $(top_srcdir)/admin/Makefile.common cvs-clean + +#>+ 3 +kde-rpo-clean: + -rm -f *.rpo diff --git a/reference/C/CONTRIB/SAWTELL/c-lesson.1 b/reference/C/CONTRIB/SAWTELL/c-lesson.1 new file mode 100755 index 0000000..a7fdeb7 --- /dev/null +++ b/reference/C/CONTRIB/SAWTELL/c-lesson.1 @@ -0,0 +1,177 @@ + +This archive contains a complete course for you to learn the 'C' computer +language itself. + +The language used is correct conversational English, I have written the +lessons using the same language constructions which I would use if I were +teaching you directly. + +An outline of the course is available for you to read below +The course is intended to demonstrate the language +itself and a selection of the simpler standard library functions. + +I have assumed that you have had sufficient exposure to computing +to be able to use a programmer's editor of your choice and are +confident in the use of the command line interpreter, whether it +be a unix shell, or a DOS ( shudder :-) prompt. Some knowledge, +of computers and the jargon is assumed, but complicated concepts are +fully explained. In other words the intent is to teach 'C' per se, +not 'the fundamentals of how to program a computer using 'C' as +a teaching medium.' + +'C' is not a computer language for rank beginners. Start with +an interpretive language and proceed to a compiled language +which has an extensive error message vocabulary and run-time +checking facilities. In the interests of speed of execution 'C' +does very little to protect you from yourself! + +Throughout the course the fact that a compiler is a translater +from a high level language to assembler code is kept to the fore, +you are frequently advised to examine the assembler code which is +output by the compiler. Some minimal knowledge of computer architecture +is therefore assumed. + +Whilst I have taken considerable care to ensure that this material is +free of errors I am well aware that to err is a common human failing, +and in this I don't claim to be different from anybody else. +Therefore your gentle critique is welcome together with notification +of any factual errors. + +It is planned to make the lessons available as a printed book, +complete with a programme diskette if there is sufficient interest. + + Syllabus for the 'C' Language Course. + + + 1 a) Historical introduction to the Language. + + b) Demonstration of a very simple program. + + c) Brief explanation of how the computer turns + your program text into an executing program. + + d) The basic differences between 'C' and other languages. + The advantages and disadvantages. + + We make the assumption that you are able to turn on your machine, + use the Operating System at the Control Line Interpreter prompt + "$ ", "c:>" or whatever, and to use an editor to enter program text. + + + 2 a) How the 'C' language arranges for the storage of data. + An explanation of the keywords associated with data. + The storage classes:- static auto volatile const. + The variable types:- char int long float double + The meaning of:- signed unsigned + + b) Introduction to the concept of pointers. + + c) Explanation of reading from the keyboard and writing to the screen. + i.e. printf and scanf, the print formatted and scan formatted + functions. + + d) The use of arguments to the main() function, argc argv env. + + e) A simple program to format text. + + + 3 Structures, arrays and pointers. + + a) Explanation of more coplex data structures. + b) Programs which demonstrate uses of pointers. + + 4 The operators of the language, arithmetic, pointer, logical, bitwise. + + a) Precedence. + b) The unique bit and shifting operators. + ( for a high level language ) + + 5 a) The Preprocesser. + b) Header files + + What they are and what you put in them, both your own and + those provided by the 'C' compiler vendor. + + A simple title which includes all sorts of things, + both very useful and a number of traps. + + 6 The library, why we have them and some of the more useful routines. + + a) How to read the book. + b) The string functions as an example. + + 7 a) Mistakes and how avoid making them. + b) Debugging strategies. + c) The assert macro. + + 8 a) More on the representation of data vis. struct, typdef. + + b) Tables of all sorts. + Arrays of structures. + Pre-initialisation of data structures. + ( Including jump or dispatch tables ) + The bit-field. + + c) Use of header files in this. + + + 9 a) The control structures of the language, what (not) to use and when. + + + 10 a) File IO + + This is an enormous subject and we we will + really only just scratch on the surface. + + + 11 a) Lint, and more on errors / bugs and how to avoid them. + + + 12 The stack and a quick dip into assembler + + a) A study of the function calling mechanism used by most 'C' + compilers and the effect on compiler output code of using + the register storage class and the optimiser. + + 13 The heap. + + a) The 'heap', it's management, malloc(), calloc() and free(). + + + 14 Portability Issues. + + a) Defaults for storage sizes. + b) 'endianism'. Yes, there are big-endian and little-endian computers! + c) Functions which can be called with a variable number of arguments. + + + 15 Sample programs. + + Much is to be gained from examining public domain packages + examining the code and reviewing the author's style. + We will look at a number of functions and complete packages. + in particular we will examine a number of sorting functions, + a multi-threading technique, queues, lists, hashing, and trees. + + + /* ----------------------------------------- */ + +Copyright notice:- + +(c) 1993 Christopher Sawtell. + +I assert the right to be known as the author, and owner of the +intellectual property rights of all the files in this material, +except for the quoted examples which have their individual +copyright notices. Permission is granted for onward copying, +but not modification, of this course and its use for personal +study only, provided all the copyright notices are left in the +text and are printed in full on any subsequent paper reproduction. + +-- + +----------------------------------------------------------------------+ + | NAME Christopher Sawtell | + | SMAIL 215 Ollivier's Road, Linwood, Christchurch, 8001. New Zealand.| + | EMAIL chris@gerty.equinox.gen.nz | + | PHONE +64-3-389-3200 ( gmt +13 - your discretion is requested ) | + +----------------------------------------------------------------------+ diff --git a/reference/C/CONTRIB/SAWTELL/c-lesson.2 b/reference/C/CONTRIB/SAWTELL/c-lesson.2 new file mode 100755 index 0000000..7fd15fd --- /dev/null +++ b/reference/C/CONTRIB/SAWTELL/c-lesson.2 @@ -0,0 +1,233 @@ + Lesson One. + +Some Historical Background. + +The 'C' programming language was designed and developed by Brian Kernighan, and +Dennis Ritchie at The Bell Research Labs. 'C' is a Language specifically +created +in order to allow the programmer access to almost all of the machine's +internals +- registers, I/O slots and absolute addresses. However, at the same time, +'C' allows for as much data hiding and programme text modularisation as is +needed to allow very complex multi-programmer projects to be constructed in an +organised and timely fashion. During the early 1960s computer Operating Systems +started to become very much more complex with the introduction of +multi-terminal +and multi-process capabilities. Prior to this time Operating Systems had been +carefully and laboriously crafted using assembler codes, and many programming +teams realised that in order to have a working o/s in anything like a +reasonable time this was now longer economically feasible. This then was the +motivation to produce the 'C' Language, which was first implemented in +assembler on a Digital Equipment Corporation PDP-7. Of course once a simple +assembler version was working it was possible to rewrite the compiler in 'C' +itself. This was done in short order and therefore as soon as the PDP-11 was +introduced by DEC it was only necessary to change the code generator section +of the compiler and the new machine had a compiler in just a few weeks. 'C' was +then used to implement the UNIX o/s. This means, that a complete UNIX can be +transported, or to use the simple jargon of today; 'ported to a new machine in +literally just a few months by a small team of competent programmers. + +Enough of the past. Lets see the various actions, or compilation phases through +which the `C' compilation system has to go in order that your file of `C' +program text can be converted working program. + +Assuming that you are able to work an editor and can enter a script and create +a file. Please enter the following tiny program. + +#ident "@(#) Hello World - my first program" + +#include + +char *format = "%s", + *hello = "Hello World...\n"; + +main() +{ + printf ( format, hello ); + } + +Now save it in a file called hello.c. Lower case is allowed - encouraged, no +less - under the UNIX operating system. + +Now type: + +cc -o hello hello.c + +The computer will apparently pause for a few moments and then the +Shell, or Command Line Interpreter prompt will re-appear. + +Now type: + +hello + +Lo and behold the computer will print + +Hello World... + +Let's just look at what the computer did during the little pause. + +The first action is to activate a preliminary process called the pre-processor. +In the case of hello.c all it does is to replace the line + +#include + +with the file stdio.h from the include files library. The file stdio.h provides +us with a convenient way of telling the compiler that all the i/o functions +exist. There are a few other little things in stdio.h but they need not +concern us at this stage. + +In order to see what the pre-processor actually outputs, you might like to +issue the command: + +cc -P hello.c + +The 'cc' command will activate the 'C' compilation system and the -P option +will stop the compilation process after the pre-processing stage, and another +file will have appeared in your directory. Have a look, find hello.i and use +the editor in view mode to have a look at it. So issue the command: + +view hello.i + +You will see that a number of lines of text have been added at the front of the +hello.c program. What's all this stuff? Well, have a look in the file called +/usr/include/stdio.h again using the view command. + +view /usr/include/stdio.h + +Look familiar? + +Now the next stage of getting from your program text to an executing program is +the compilation of your text into an assembler code program. After all that is +what a compiler is for - to turn a high level language script into a program. +Lets see what happens by issuing the command + +cc -S hello.c + +Once again there is another file in your directory - this time with a .s +suffix. + +Lets have a look at it in the same way as the .i file + +view hello.s + +You will doubtless notice a few recognizable symbols and what appears to be a +pile of gibberish. The gibberish is in fact the nmemonics for the machine +instructions which are going to make the computer do what you have programmed +it to do. + +Now this assembler code has to be turned into machine instructions. +To do this issue the command. + +cc -g -c hello.s + +Now, yet again there is another file in your directory - this time the suffix +is ".o". This file is called the object file. It contains the machine +instructions corresponding exactly to the nmemonic codes in the .s file. +If you wish you can look at these machine codes using one of the commands +available to examine object files. + +dis -L -t .data hello.o >hello.dis + +The output from these commands won't be very meaningful to you at this stage, +the purpose of asking you to use them is merely to register in your mind the +fact that an object file is created as a result of the assembly process. + +The next stage in the compilation process is called by a variety of names - +"loading", "linking", "link editing". What happens is that the machine +instructions in the object file ( .o ) are joined to many more instructions +selected from an enormous collection of functions in a library. This phase of +the compilation process is invoked by the command:- + +cc -o hello hello.o + +Now, at last, you have a program to execute! So make it do it's thing by +putting the name of the executable file as a response to the Shell or Command +Line Interpreter prompt. + +hello + +Presto, the output from your program appears on the screen. + +Hello World... + +You are now allowed to rejoice and have a nice warm fuzzy to hold! +You have successfully entered a `C' program, compiled it, linked it, and +finally, executed it! + +Having gone through all the various stages of editing, pre-processing, +compiling, assembling, linking, and finally executing, by hand as it were, you +can now rest assured that all the stages are automated by the 'cc' command, and +you can forget how to invoke them! Just remember that the computer has to do +them in order for you to have a program to execute. + +The single command you use to activate the C Compiler is: + +cc -o hello hello.c + +The word after the -o option is the name of the executable file, if you don't +provide a name here the compiler dreams up the name "a.out". The source file +MUST have the .c extension otherwise the compiler complains and stops working. + +Notes: + + The command names used in the above text are those of standard UNIX, + Your particular system may well use a different name for the 'C' compiler. + bcc - for Borland 'C'. + gcc - GNU 'C', which is standard on the Linux operating system. + lc - Lattice 'C', available on IBM and clone P.C.s as well as the Amiga. + Check in the Documentation which came with your compiler. + The same notions apply to the text editor. + +Differences between 'C' and other languages. + +In the years since 'C' was developed it has changed remarkable little. +This fact is a bouquet to the authors, who had the vision and understanding to +create a language which has endured so well. The strengths and weaknesses +should be pointed out here. + +The big plus is that it is possible to do everything ( well at least 99.9% ) in +'C' while other languages compel you to write a procedure, subroutine or +function in assembler code. + +'C' has very good facilities for creating tables of constant data within the +source file. + +'C' doesn't do very much to protect you from yourself. This means that the +resulting code executes faster than most other high level languages, but a much +greater degree of both care and understanding is demanded from the programmer. + +'C' is not a closely typed language, although the newer compilers are offering +type checking as part of the language itself as opposed to having to use a +separate program for mechanised debugging. + +'C' is a small language with very few intrinsic operations. +All the heavy work is done by explicit library function calls. + +'C' allows you to directly and conveniently access most of the internals of +the machine ( the memory, input output slots, and CPU registers ) from the +language without having to resort to assembler code. + +'C' compilers have an optimisation phase which can be invoked if desired. +The output code can be optimised for either speed or memory usage. The code +will be just as good as that produced by an assembly code programmer of normal +skill - real guru programmers can do only slightly better. + +Copyright notice:- + +(c) 1993 Christopher Sawtell. + +I assert the right to be known as the author, and owner of the +intellectual property rights of all the files in this material, +except for the quoted examples which have their individual +copyright notices. Permission is granted for onward copying, +but not modification, of this course and its use for personal +study only, provided all the copyright notices are left in the +text and are printed in full on any subsequent paper reproduction. + +-- + +----------------------------------------------------------------------+ + | NAME Christopher Sawtell | + | SMAIL 215 Ollivier's Road, Linwood, Christchurch, 8001. New Zealand.| + | EMAIL chris@gerty.equinox.gen.nz | + | PHONE +64-3-389-3200 ( gmt +13 - your discretion is requested ) | + +----------------------------------------------------------------------+ diff --git a/reference/C/CONTRIB/SAWTELL/c-lesson.3 b/reference/C/CONTRIB/SAWTELL/c-lesson.3 new file mode 100755 index 0000000..8d6dac2 --- /dev/null +++ b/reference/C/CONTRIB/SAWTELL/c-lesson.3 @@ -0,0 +1,629 @@ + Lesson 2 + + Data Storage Concepts. + + It has been stated that "data + algorithms = programs". + This Lesson deals with with the first part of the addition sum. + + All information in a computer is stored as numbers represented using the +binary number system. The information may be either program instructions or +data elements. The latter are further subdivided into several different types, +and stored in the computer's memory in different places as directed by the +storage class used when the datum element is defined. + +These types are: + + a) The Character. + + This is a group of 8 data bits and in 'C' represents either + a letter of the Roman alphabet, or a small integer in the range of 0 + through to +255. So to arrange for the compiler to give you a named + memory area in which to place a single letter you would "say": + + char letter; + + at the beginning of a program block. You should be aware that + whether or not a char is signed or unsigned is dependant + on the design of the processor underlying your compiler. + In particular, note that both the PDP-11, and VAX-11 made by + Digital Equipment Corporation have automatic sign extention of +char. + This means that the range of char is from -128 through to +127 + on these machines. Consult your hardware manual, there may be + other exceptions to the trend towards unsigned char as the +default. + + This test program should clear things up for you. + +/* ----------------------------------------- */ + +#ident "@(#) - Test char signed / unsigned."; + +#include + +main() +{ + char a; + unsigned char b; + + a = b = 128; + a >>= 1; + b >>= 1; + printf ( "\nYour computer has %ssigned char.\n\n", a == b ? "un" : "" ); + } + +/* ----------------------------------------- */ + + Here ( Surprise! Surprise! ) is its output on a machine which has + unsigned chars. + +Your computer has unsigned char. + + Cut this program out of the news file. Compile and execute it on + your computer in order to find out if you have signed or +unsigned char. + + b) The Integers. + + As you might imagine this is the storage type in which to store whole + numbers. There are two sizes of integer which are known as short and long. + The actual number of bits used in both of these types is Implementation + Dependent. This is the way the jargonauts say that it varies from computer + to computer. Almost all machines with a word size larger than sixteen bits + have the the long int fitting exactly into a machine word and +a short int + represented by the contents of half a word. It's done this way because + most machines have instructions which will perform arithmetic +efficiently + on both the complete machine word as well as the half-word. +For the + sixteen bit machines, the long integer is two machine words +long, + and the short integer is one. + + short int smaller_number; + long int big_number; + + Either of the words short or long may be omitted as a default is + provided by the compiler. Check your compiler's documentation +to see + which default you have been given. Also you should be aware +that some + compilers allow the you to arrange for the integers declared +with just + the word "int" to be either short or long. The range for a +short int on + a small computer is -32768 through to +32767, and for a long +int + -4294967296 through to +4294967295. + + c) The Real Numbers. + + Sometimes known as floating point numbers this number representation + allows us to store values such as 3.141593, or -56743.098. So, using + possible examples from a ship design program you declare floats and + doubles like this: + + float length_of_water_line; /* in meters */ + double displacement; /* in grammes */ + + In the same way that the integer type offers two sizes so does the + floating point representation. They are called float and double. Taking + the values from the file /usr/include/values.h the ranges which can be + represented by float and double are: + + MAXFLOAT 3.40282346638528860e+38 + MINFLOAT 1.40129846432481707e-45 + MAXDOUBLE 1.79769313486231470e+308 + MINDOUBLE 4.94065645841246544e-324 + + However you should note that for practical purposes the maximum + number of significant digits that can be represented by a +float + is approximately six and that by a double is twelve. Also you +should + be aware that the above numbers are as defined by the IEEE +floating + point standard and that some older machines and compilers do +not + conform. All small machines bought retail will conform. If you +are + in doubt I suggest that refer to your machine's documentation +for + the whole and exact story! + + + d) Signed and unsigned prefixes. + + For both the character and integer types the declaration can be + preceded by the word "unsigned". This shifts the range so that +0 + is the minimum, and the maximum is twice that of the signed +data + type in question. It's useful if you know that it is +impossible + for the number to go negative. Also if the word in memory is +going + to be used as a bit pattern or a mask and not a number the use +of + unsigned is strongly urged. If it is possible for the sign bit +in + the bit pattern to be set and the program calls for the bit +pattern + to be shifted to the right, then you should be aware that the +sign + bit will be extended if the variable is not declared unsigned. + The default for the "int" types is always "signed", and, as +discussed + above that of the "char" is machine dependent. + + This completes the discussion on the allocation of data types, except to + say that we can, of course, allocate arrays of the simple types simply by + adding a pair of square brackets enclosing a number which is the size of + the array after the variable's name: + + char client_surname[31]; + + This declaration reserves storage for a string of 30 characters plus the + NULL character of value zero which terminates the string. + + Structures. + + Data elements which are logically connected, for example - to use the + example alluded to above - the dimensions and other details about a +sea + going ship, can be collected together as a single data unit called a + struct. One possible way of laying out the struct in the source code +is: + +struct ship /* The word "ship" is known as the structure's "tag". */ +{ + char name[30]; + double displacement; /* in grammes */ + float length_of_water_line; /* in meters */ + unsigned short int number_of_passengers; + unsigned short int number_of_crew; + }; + + Note very well that the above fragment of program text does NOT + allocate any storage, it merely provides a named template to +the + compiler so that it knows how much storage is needed for the + structure. The actual allocation of memory is done either like +this: + +struct ship cunarder; + + Or by putting the name of the struct variable between the "}" +and + the ";" on the last line of the definition. Personally I don't + use this method as I find that the letters of the name tend to +get + "lost" in the - shall we say - amorphous mass of characters +which + make up the definition itself. + + The individual members of the struct can have values assigned to + them in this fashion: + + cunarder.displacement = 97500000000.0; + cunarder.length_of_water_line = 750.0 + cunarder.number_of_passengers = 3575; + cunarder.number_of_crew = 4592; + + These are a couple of files called demo1.c & demo1a.c which contain + small 'C' programs for you to compile. So, please cut them out +of the + news posting file and do so. + + +---------------------------------------------------------------------- +#ident demo1.c /* If your compiler complains about this line, chop it out */ +#include + +struct ship +{ + char name[31]; + double displacement; /* in grammes */ + float length_of_water_line; /* in meters */ + unsigned short int number_of_passengers; + unsigned short int number_of_crew; + }; + +char *format = "\ +Name of Vessel: %-30s\n\ + Displacement: %13.3f\n\ + Water Line: %5.1f\n\ + Passengers: %4d\n\ + Crew: %4d\n\n"; + +main() +{ + struct ship cunarder; + + cunarder.name = "Queen Mary"; /* This is the bad line. */ + cunarder.displacement = 97500000000.0; + cunarder.length_of_water_line = 750.0 + cunarder.number_of_passengers = 3575; + cunarder.number_of_crew = 4592; + + printf ( format, + cunarder.name, + cunarder.displacement, + cunarder.length_of_water_line, + cunarder.number_of_passengers, + cunarder.number_of_crew + ); + } + +---------------------------------------------------------------------- + + Why is the compiler complaining at line 21? + Well C is a small language and doesn't have the ability to allocate + strings to variables within the program text at run-time. This + program shows the the correct way to copy the string "Queen +Mary", + using a library routine, into the structure. + + +---------------------------------------------------------------------- +#ident demo1a.c /* If your compiler complains about this line, chop it out */ +#include + +/* +** This is the template which is used by the compiler so that +** it 'knows' how to put your data into a named area of memory. +*/ + +struct ship +{ + char name[31]; + double displacement; /* in grammes */ + float length_of_water_line; /* in meters */ + unsigned short int number_of_passengers; + unsigned short int number_of_crew; + }; + +/* +** This character string tells the printf() function how it is to output +** the data onto the screen. Note the use of the \ character at the end +** of each line. It is the 'continue the string on the next line' flag +** or escape character. It MUST be the last character on the line. +** This technique allows you to produce nicely formatted reports with all the +** ':' characters under each other, without having to count the characters +** in each character field. +*/ + +char *format = "\n\ +Name of Vessel: %-30s\n\ + Displacement: %13.1f grammes\n\ + Water Line: %5.1f metres\n\ + Passengers: %4d\n\ + Crew: %4d\n\n"; + +main() +{ + struct ship cunarder; + + strcpy ( cunarder.name, "Queen Mary" ); /* The corrected line */ + cunarder.displacement = 97500000000.0; + cunarder.length_of_water_line = 750.0; + cunarder.number_of_passengers = 3575; + cunarder.number_of_crew = 4592; + + printf ( format, + cunarder.name, + cunarder.displacement, + cunarder.length_of_water_line, + cunarder.number_of_passengers, + cunarder.number_of_crew + ); + } + +---------------------------------------------------------------------- + + I'd like to suggest that you compile the program demo1a.c and execute it. + +$ cc demo1a.c +$ a.out + +Name of Vessel: Queen Mary + Displacement: 97500000000.0 grammes + Water Line: 750.0 metres + Passengers: 3575 + Crew: 4592 + + Which is the output of our totally trivial program to demonstrate + the use of structures. + + Tip: + + To avoid muddles in your mind and gross confusion in other minds + remember that you should ALWAYS declare a variable using a name which is + long enough to make it ABSOLUTELY obvious what you are talking about. + + Storage Classes. + + The little dissertation above about the storage of variables was + concerned with the sizes of the various types of data. There is + just the little matter of the position in memory of the variables' + storage. + + 'C' has been designed to maximise the the use of memory by allowing you + to re-cycle it automatically when you have finished with it. + A variable defined in this way is known as an 'automatic' one. Although + this is the default behaviour you are allowed to put the word 'auto' in + front of the word which states the variable's type in the definition. + It is quite a good idea to use this so that you can remind yourself + that this variable is, in fact, an automatic one. There are three other + storage allocation methods, 'static' and 'register', and 'const'. + The 'static' method places the variable in main storage for the whole + of the time your program is executing. In other words it kills the + 're-cycling' mechanism. This also means that the value stored there + is also available all the time. The 'register' method is very machine + and implementation dependent, and also perhaps somewhat archaic in + that the optimiser phase of the compilation process does it all for + you. For the sake of completeness I'll explain. Computers have a small + number of places to store numbers which can be accessed very quickly. + These places are called the registers of the Central Processing Unit. + The 'register' variables are placed in these machine registers instead +of + stack or main memory. For program segments which are tiny loops the +speed + at which your program executes can be enhanced quite remarkably. + The optimiser compilation phase places as many of your variables into + registers as it can. However no machine can decide which of the +variables + should be placed in a register, and which may be left in memory, so if + your program has many variables and two or three should be register +ones + then you should specify which ones the compiler. + + All this is dealt with at much greater detail later in the course. + + Pointers. + + 'C' has the very useful ability to set up pointers. These are memory + cells which contain the address of a data element. The variable name is + preceeded by a '*' character. So, to reserve an element of type char +and + a pointer to an element of type char, one would say. + +char c; +char *ch_p; + + I always put the suffix '_p' on the end of all pointer variables + simply so that I can easily remember that they are in fact pointers. + + There is also the companion unary operator '&' which yields the + address of the variable. So to initialize our pointer ch_p to point + at the char c, we have to say. + + ch_p = &c; + + Note very well that the process of indirection can procede to any + desired depth, However it is difficult for the puny brain of a normal + human to conceptualize and remember more that three levels! So be +careful + to provide a very detailed and precise commentry in your program if + you put more than two or three stars. + + + Getting data in and out of your programs. + + As mentioned before 'C' is a small language and there are no intrinsic + operators to either convert between binary numbers and ascii + characters or to transfer information to and fro between the + computer's memory and the peripheral equipment, such as terminals or + disk stores. + + This is all done using the i/o functions declared in the file stdio.h + which you should have examined earlier. Right now we are going to look + at the functions "printf" and "scanf". These two functions together + with their derivatives, perform i/o to the stdin and stdout files, + i/o to nominated files, and internal format conversions. This means + the conversion of data from ascii character strings to binary numbers + and vice versa completely within the computer's memory. It's more + efficient to set up a line of print inside memory and then to send the + whole line to the printer, terminal, or whatever, instead of + "squirting" the letters out in dribs and drabs! + + Study of them will give you understanding of a very convenient way to + talk to the "outside world". + + So, remembering that one of the most important things you learn in + computing is "where to look it up", lets do just that. + If you are using a computer which has the unix operating system, + find your copy of the "Programmer Reference Manual" and turn to the + page printf(3S), alternatively, if your computer is using some other + operating system, then refer to the section of the documentation which + describes the functions in the program library. + + You will see something like this:- + + NAME + printf, fprintf, sprintf - print formatted +output. + + SYNOPSIS + #include + + int printf ( format [ , arg ] ... ) + char *format; + + int fprintf ( stream, format [ , arg ] ... ) + FILE *stream; + char *format; + + int sprintf ( s, format [ , arg ] ... ) + char *s, *format; + + DESCRIPTION + + etc... etc... + + The NAME section above is obvious isn't it? + + The SYNOPSIS starts with the line #include . This tells + you that you MUST put this #include line in your 'C' source code + before you mention any of the routines. The rest of the paragraph + tells you how to call the routines. The " [ , arg ] ... " heiroglyph + in effect says that you may have as many arguments here as you wish, + but that you need not have any at all. + + The DESCRIPTION explains how to use the functions. + + Important Point to Note: + + Far too many people ( including the author ) ignore the fact that + the printf family of functions return a useful number which can be + used to check that the conversion has been done correctly, and that + the i/o operation has been completed without error. + + Refer to the format string in the demonstration program above for + an example of a fairly sophisticated formatting string. + + In order to fix the concepts of printf in you mind, you + might care to write a program which prints some text in three ways: + +a) Justified to the left of the page. ( Normal printing. ) +b) Justified to the right of the page. +c) Centred exactly in the middle of the page. + + Suggestions and Hint. + + Set up a data area of text using the first verse of "Quangle" as data. + Here is the program fragment for the data:- + +/* ----------------------------------------- */ + +char *verse[] = +{ + "On top of the Crumpetty Tree", + "The Quangle Wangle sat,", + "But his face you could not see,", + "On account of his Beaver Hat.", + "For his Hat was a hundred and two feet wide.", + "With ribbons and bibbons on every side,", + "And bells, and buttons, and loops, and lace,", + "So that nobody ever could see the face", + "Of the Quangle Wangle Quee.", + NULL + }; + +/* ----------------------------------------- */ + + Cut it out of the news file and use it in a 'C' program file called + verse.c + + Now write a main() function which uses printf alone for (a) & (b) + You can use both printf() and sprintf() in order to create + a solution for (c) which makes a good use of the capabilities + of the printf family. The big hint is that the string controlling + the format of the printing can change dynamically as program execution + proceeds. A possible solution is presented in the file verse.c which is + appended here. I'd like to suggest that you have a good try at making + a program of you own before looking at my solution. + ( One of many I'm sure ) + +/* ----------------------------------------- */ + +#include + +char *verse[] = +{ + "On top of the Crumpetty Tree", + "The Quangle Wangle sat,", + "But his face you could not see,", + "On account of his Beaver Hat.", + "For his Hat was a hundred and two feet wide.", + "With ribbons and bibbons on every side,", + "And bells, and buttons, and loops, and lace,", + "So that nobody ever could see the face", + "Of the Quangle Wangle Quee.", + NULL + }; + +main() +{ + char **ch_pp; + + /* + ** This will print the data left justified. + */ + + for ( ch_pp = verse; *ch_pp; ch_pp++ ) printf ( "%s\n", *ch_pp ); + printf( "\n" ); + + /* + ** This will print the data right justified. + ** + ** ( As this will print a character in column 80 of + ** the terminal you should make sure any terminal setting + ** which automatically inserts a new line is turned off. ) + */ + + for ( ch_pp = verse; *ch_pp; ch_pp++ ) printf ( "%79s\n", *ch_pp ); + printf( "\n" ); + + /* + ** This will centre the data. + */ + + for ( ch_pp = verse; *ch_pp; ch_pp++ ) + { + int length; + char format[10]; + + length = 40 + strlen ( *ch_pp ) / 2; /* Calculate the +field length */ + sprintf ( format, "%%%ds\n", length ); /* Make a format +string. */ + printf ( format, *ch_pp ); /* Print line of +verse, using */ + } /* generated format +string */ + printf( "\n" ); + } + +/* ----------------------------------------- */ + + If you cheated and looked at my example before even attempting + to have a go, you must pay the penalty and explain fully why + there are THREE "%" signs in the line which starts with a call + to the sprintf function. It's a good idea to do this anyway! + + + So much for printf(). Lets examine it's functional opposite - scanf(), + + Scanf is the family of functions used to input from the outside world + and to perform internal format conversions from character strings to + binary numbers. Refer to the entry scanf(3S) in the Programmer + Reference Manual. ( Just a few pages further on from printf. ) + + The "Important Point to Note" for the scanf family is that the + arguments to the function are all POINTERS. The format string has to + be passed in to the function using a pointer, simply because this + is the way 'C' passes strings, and as the function itself has to store + its results into your program it ( the scanf function ) has to "know" + where you want it to put them. + +Copyright notice:- + +(c) 1993 Christopher Sawtell. + +I assert the right to be known as the author, and owner of the +intellectual property rights of all the files in this material, +except for the quoted examples which have their individual +copyright notices. Permission is granted for onward copying, +but not modification, of this course and its use for personal +study only, provided all the copyright notices are left in the +text and are printed in full on any subsequent paper reproduction. + +-- + +----------------------------------------------------------------------+ + | NAME Christopher Sawtell | + | SMAIL 215 Ollivier's Road, Linwood, Christchurch, 8001. New Zealand.| + | EMAIL chris@gerty.equinox.gen.nz | + | PHONE +64-3-389-3200 ( gmt +13 - your discretion is requested ) | + +----------------------------------------------------------------------+ diff --git a/reference/C/CONTRIB/SAWTELL/c-lesson.4 b/reference/C/CONTRIB/SAWTELL/c-lesson.4 new file mode 100755 index 0000000..a6072e0 --- /dev/null +++ b/reference/C/CONTRIB/SAWTELL/c-lesson.4 @@ -0,0 +1,313 @@ + Lesson 3 + + Arrays and Pointers. + + You can allocate space for an array of elements at compile time with fixed + dimension sizes of any data type, even functions and structs. + So these are legal array definitions: + + char name[30]; /* An array of 30 signed characters. */ + char *strings[50]; /* 50 pointers to strings. */ + unsigned long int *(*func)()[20];/* An array of pointers to functions which +*/ + /* return pointers to unsigned long ints. */ + + You can declare a pointer to point at any type of data element, and as in + the array situation above functions and structs are included. + +struct ship +{ + char name[30]; + double displacement; /* in grammes */ + float length_of_water_line; /* in meters */ + unsigned short int number_of_passengers; + unsigned short int number_of_crew; + }; + + So using the ship concept from Lesson 2 you can declare a pointer to point + at one of the ship structs in an array. + +struct ship *vessel_p; + + Note the use of the suffix "_p". + This is my way of reminding myself that the variable is a pointer. + +struct ship fleet[5]; /* This allocates enough storage for 5 ships' info. +*/ + + Now lets set the pointer to point at the first vessel in the fleet. + + vessel_p = fleet; + + This pointer can be made to point at other ships in the fleet by + incrementing it or doing additive arithmetic on it: + + vessel_p++; /* point a the next ship in the fleet array. */ + vessel_p = fleet + 3; + + Also we can find out the index of the ship in the fleet at which we are + pointing: + + i = vessel_p - fleet; + + It is also legal to find out the separation of two pointers pointing at + elements in an array: + + d = vessel_p - another_vessel_p; /* This gives the separation in elements. */ + + So summarising, pointers may be, incremented, decremented, and subtracted + one from another or have a constant subtracted from them. Any other + mathematical operation is meaningless and not allowed. + + Assembler programmers should note that while the pointer variables contain a + byte machine address, when the arithmetic is done using pointers the +compiler + also issues either a multiply or a divide as well as the add or subtract + instruction so that the result is ALWAYS expressed in elements rather than + bytes. Have a go and write yourself a trivial little program, and have a + look at the compiler ouput code. Lesson 1 told you how! + + When using a pointer to reference a structure we have to use a "pointer + offset" operator in order to access the member of the struct we require: + + vessel_p = fleet; + + vessel_p->name = "Queen Mary"; + vessel_p->displacement = 97500000000.0; + vessel_p->length_of_water_line = 750.0 + vessel_p->number_of_passengers = 3575; + vessel_p->number_of_crew = 4592; + + Remember: + + It's a "." when accessing a struct which is in storage declared in + the program. + + It's a "->" when accessing a struct at which a pointer is pointing. + + Initialisation of arrays. + + 'C' has the facility to initialise variables in a program script. + + Some examples: + + char *qbf = "The quick brown fox jumped over the lazy dogs back"; + + int tic_tac_toe[3][3] = + { + { 1, 2, 3 }, + { 4, 5, 6 }, + { 7, 8, 9 } + }; + + struct ship fleet[2] = + { + { "Queen Elizabeth", 97500000000.0, 750.0, 3575, 4592 }, + { "Queen Mary", 115000000000.0, 875.0, 4500, 5500 } + }; + + Take a careful note of where the commas and semi-colons go ( and don't go )! + + Initialised Tables of Indeterminate Length. + + One nice feature 'C' offers is that it is able to calculate + the amount of storage required for a table by 'looking' at the number + of initialisers. + +char *verse[] = +{ + "On top of the Crumpetty Tree", + "The Quangle Wangle sat,", + "But his face you could not see,", + "On account of his Beaver Hat.", + "For his Hat was a hundred and two feet wide.", + "With ribbons and bibbons on every side,", + "And bells, and buttons, and loops, and lace,", + "So that nobody ever could see the face", + "Of the Quangle Wangle Quee." + NULL + }; + + Note the * character in the definition line. This means that we are going + to make an array of pointers to variables of type char. As there is no + number between the [ ] characters the compiler calculates it for us. + With this kind of set-up it is nice and easy to add extra information + to the table as program development proceeds. The compiler will calculate + the new dimension for you. The point to remember is that the program has to + know - from the contents of the table - that it has come to the end of the + table! So you have to make a special entry which CANNOT under any + circumstances be a real data element. We usually use NULL for this. + The other way is to calculate the size of the table by using the sizeof + operator - Note that although use of sizeof looks like a function call + it is in fact an intrinsic operator of the language. The result is + available at compile time. So one can say:- + + #define SIZE_OF_VERSE sizeof verse + + There is one final initialised data type, the enum. It is a fairly recent + addition to the language. + + enum spectrum { red, orange, yellow, green, blue, indigo, violet } colour; + + In this construct the first symbol is given the value of 0 and for each + following symbol the value is incremented. It is however possible to assign + specific values to the symbols like this: + + enum tub + { anorexic = 65, + slim = 70, + normal = 80, + fat = 95, + obese = 135 + }; + + Some compilers are bright enough to detect that it is an error if an + attempt is made to assign a value to an enum variable which is not in + the list of symbols, on the other hand many are not. Take care! In + practice there is little difference between the enum language construct + and a number of define statements except perhaps aesthetics. Here is + another trivial program which demonstrates the use of enum and a + pre-initialised array. + +#include + +enum spectrum { red, orange, yellow, green, blue, indigo, violet } colour; + +char *rainbow[] = { "red", "orange", "yellow", "green", + "blue", "indigo", "violet" }; + +main() +{ + for ( colour = red; colour <= violet; colour++ ) + { + printf ( "%s ", rainbow[colour]); + } + printf ( "\n" ); + } + + The output of which is ( not surprisingly ): + +red orange yellow green blue indigo violet + + One quite advanced use of initialised arrays and pointers is the jump or + dispatch table. This is a efficient use of pointers and provides a very much + better ( In my opinion ) method of controlling program flow than a maze + of case or ( heaven forbid ) if ( ... ) goto statements. + + Please cut out this program, read and compile it. + ------------------------------------------------------------------------ + +char *ident = "@(#) tellme.c - An example of using a pointer to a function."; + +#include +#include +#include + +/* +These declarations are not in fact needed as they are all declared extern in +math.h. However if you were to use routines which are not in a library and +therefore not declared in a '.h' file you should declare them. Remember you +MUST declare external routines which return a type other than the int type. + +extern double sin (); +extern double cos (); +extern double tan (); +extern double atof (); +*/ + +struct table_entry +{ + char *name; /* The address of the character string. */ + double (*function)(); /* The address of the entry point of the function. */ + }; + +typedef struct table_entry TABLE; + +double help ( tp ) +TABLE *tp; +{ printf ( "Choose one of these functions:- " ); + fflush ( stdout ); + for ( ; tp -> name; tp++ ) printf ( "%s ", tp -> name ); + printf ( "\nRemember the input is expressed in Radians\n" ); + exit ( 0 ); + return ( 0.0 ); /* Needed to keep some nit-picking dumb compilers happy! */ + } + +/* + * This is the array of pointers to the strings and function entry points. + * Is is initialised at linking time. You may add as many functions as you + * like in here PROVIDED you declare them to be extern, either in some .h + * file or explicitly. + */ + +TABLE interpretation_table [ ] = +{ + { "sin", sin }, + { "tan", tan }, + { "cos", cos }, + { "help", help }, + { NULL, NULL } /* To flag the end of the table. */ + }; + +char *output_format = { "\n %s %s = %g\n" }; +extern int errno; +extern void perror(); + +main( argc, argv ) +int argc; +char **argv; +{ + TABLE *tp; + double x, answer; + + if ( argc > 3 ) + { + errno = E2BIG; + perror ( "tellme" ); + exit ( -1 ); + } + + for (;;) /* This is the way to set up a continuous loop. */ + { + for ( tp = interpretation_table; + ( tp -> name && strcmp ( tp -> name, argv[1] )); + tp++ + ) ; /* Note use of empty for loop to position tp. */ + + if ( tp -> function == help ) (*tp -> function )( interpretation_table ); + if ( tp -> name == NULL ) + { + printf ( "Function %s not implemented yet\n", argv[1] ); + exit ( 1 ); + } + break; /* Leave the loop. */ + } + + x = atof ( argv[2] ); /* Convert the character string to a double. */ + answer = ( *tp -> function )( x );/* Execute the desired function. */ + printf ( output_format, /* Pointer to printf()'s format string. */ + argv[1], /* Pointer to the name of the function. */ + argv[2], /* Pointer to the input number ascii string. */ + answer /* Value ( in double floating point binary ) */ + ); + } + +Copyright notice:- + +(c) 1993 Christopher Sawtell. + +I assert the right to be known as the author, and owner of the +intellectual property rights of all the files in this material, +except for the quoted examples which have their individual +copyright notices. Permission is granted for onward copying, +but not modification, of this course and its use for personal +study only, provided all the copyright notices are left in the +text and are printed in full on any subsequent paper reproduction. + +-- + +----------------------------------------------------------------------+ + | NAME Christopher Sawtell | + | SMAIL 215 Ollivier's Road, Linwood, Christchurch, 8001. New Zealand.| + | EMAIL chris@gerty.equinox.gen.nz | + | PHONE +64-3-389-3200 ( gmt +13 - your discretion is requested ) | + +----------------------------------------------------------------------+ diff --git a/reference/C/CONTRIB/SAWTELL/c-lesson.5 b/reference/C/CONTRIB/SAWTELL/c-lesson.5 new file mode 100755 index 0000000..949fb49 --- /dev/null +++ b/reference/C/CONTRIB/SAWTELL/c-lesson.5 @@ -0,0 +1,291 @@ + +Lesson 4. + + The +operators of the language. + + I have mentioned that 'C' is a small language with most of the heavy +work +being done by explicit calls to library functions. There is however a rich +mix of intrinsic operators which allow you to perform bit level operations, +use pointers, and perform immediate operations on varables. In other words, +most of a machine's instruction set is able to be used in the object program. +At the time when 'C' was designed and first written these were unique for +a high level language. + + Lets start with a discussion about precedence. + + This really means that the compiler puts invisable parentheses into +your expression. Casting your mind back to Arithmetic in the primary school +I expect you remember the nmemonic "My Dear Aunt Sally". The 'C' language +does as well! So the following expression is correct + + 15 + 4 * 11 = 59 + + The compiler has rendered the expression as: + + 15 + ( 4 * 11 ) = 59 + + Now the 'C' language has a much larger collection of operators than +just +Multiply Divide Add Subtract, in fact much too big to try to remember the +precedence of all of them. So my recomendation is to ALWAYS put in the +parentheses, except for simple arithmetic. However, for the sake of +completeness as much as anything else, here is the list. + + First up come what are called the primary-expression operators: + + () Function. + [] Array. + . struct member ( variable ). + -> struct member ( pointer ). + + The unary operators: + + * Indirection via a Pointer. + & Address of Variable. + - Arithmetic Negative. + ! Logical Negation or Not. + ~ Bit-wise One's Complement. + ++ Increment. + -- Decrement. + sizeof Which is self explanitary. + + Now the binary operators: + + Arithmetic Operators. + + * Multiply. My + / Divide. Dear + % Modulo, or Remainder of Integer Division. + + Addition. Aunt + - Subtraction. Sally + + The Shifting Operators. + + >> Bit-wise Shift to the Right. + << Bit-wise Shift to the Left. + + Logical Relation Operators. + + < Less Than. + > Greater Than. + <= Less Than or Equal. + >= Greater Than or Equal. + == Equal. + != Not Equal. + + Bit-wise Boolean Operators. + + & Bit-wise And. + ^ Bit-wise Exclusive-or. + | Bit-wise Or. + + The Logical Operators. + + && Logical And. + || Logical Or. + + The Assignment Operators. ( They all have the same priority. ) + + = The normal assignment operator. + + The Self-referencing Assignment Operators. + + += + -= + *= + /= + %= + >>= + <<= + &= + ^= + |= + + Some explanation is in order here. The machine instructions in your +computer include a suit of what are called "immediate operand" instructions. +These instructions have one of the operands in a register and the other +is either part of the instruction word itself ( if it is numerically small +enough to fit ) or is the next word in the address space "immediately" after +the instruction code word. 'C' makes efficient use of this machine feature +by providing the above set of operations each of which translates directly +to its corresponding machine instruction. When the variable in question is a +'register' one, or the optimiser is in use, the compiler output is just +the one "immediate" machine instruction. Efficiency Personified!!! + + These two lines will make things clearer. + + a = 8; + a += 2; /* The result is 10 */ + + The exclusive-or operation is very useful you can toggle any +combination +of bits in the variable using it. + + a = 7; + a ^= 2; /* Now a is 5 */ + a ^= 2; /* and back to 7. */ + + Naturally, you can use the other operations in exactly the same way, +I'd like to suggest that you make a utterly simplistic little program +and have a look at the assembler code output of the compiler. Don't be +afraid of the assembler codes - they don't bite - and you will see +what I was on about in the paragraph above. + + Historical Note and a couple of Cautions. + + In the Oldend Days when 'C' was first written all the self-referencing +operations had the equals symbol and the operand around the other way. +Until quite recently ( unix system V release 3.0 ) the 'C' compiler had a +compatability mode and could cope with the old style syntax. + + A sample or test program is probably in order here. + +/* ----------------------------------------- */ + +#include + +char *mes[] = +{ + "Your compiler", + " understands", + " does not understand", + " the old-fashioned self-referencing style." + }; + +main() +{ + int a; + + a = 5; + a=-2; + printf ( "%s %s %s\n", mes [ 0 ], mes [ ( a == -2 ) ? 2 : 1 ], mes [ 3 +] ); + } + +/* ----------------------------------------- */ + + The 'C' compiler issued with unix System V release 3.2 seems to have +( thankfully ) dropped the compatability mode. However a collegue, who +was using an old compiler, and I spent hours trying to find this strange bug! +The cure for the problem is either to put spaces on either side of the '=' sign +or to bracket the unary minus to the operand. + + a=(-2); + a = -2; + +Either is acceptable, and might save you a lot of spleen if sombody tries +to install your work of art program on an ancient machine. + + The other caution is the use of the shifting instructions with signed +and unsigned integers. + + If you shift a signed integer to the right when the sign bit is set +then in all probability the sign will be extended. Once again a little +demo program. Please cut it out of the news file with your editor +and play with it. + +/* ----------------------------------------- */ + +#ident "#(@) shifts.c - Signed / Unsigned integer shifting demo." +#include + +#define WORD_SIZE ( sizeof ( INTEGER int ) * 8 ) +#define NIBBLE_SIZE 4 +#define NIBBLES_IN_WORD (( WORD_SIZE ) / NIBBLE_SIZE ) +#define SIGN_BIT ( 1 << ( WORD_SIZE - 1 )) + +char *title[] = +{ " Signed Unsigned", + " Signed Unsigned" + }; + +main () +{ + INTEGER int a; + unsigned INTEGER int b, mask; + int ab, i, j, bit_counter, line_counter; + + a = b = SIGN_BIT; + printf ( "%s\n\n", title [ ( WORD_SIZE == 16 ) ? 0 : 1 ] ); + + for ( line_counter = 0; line_counter < WORD_SIZE; line_counter++ ) + { + for ( ab = 0; ab < 2; ab++ ) + { + mask = SIGN_BIT; + for ( i = 0; i < NIBBLES_IN_WORD; i++ ) + { + for ( j = 0; j < NIBBLE_SIZE; j++ ) + { + printf ( "%c", ((( ab ) ? b : a ) & +mask ) ? '1' : '0' ); + mask >>= 1; + } + printf ( " " ); + } + printf ( "%s", ( ab ) ? "\n" : " " ); + if ( ab ) + { + b >>= 1; + } + else + { + a >>= 1; +#if defined(FIX_COMPILER_BUG) +# if (INTEGER == long) + a |= SIGN_BIT; /* This is a work-around for +the 3b2 compiler bug. */ +# endif +#endif + } + } + } + } + +/* ----------------------------------------- */ + + This little program might well produce some interesting surprises on +your machine in the same way it did on mine. I have an AT&T 3b2/400 and +use the K & R style compiler. Interestingly, the above program did what +I expected it to do when the integers were short, the sign bit is extended, +but when the integers are long the sign bit is NOT extended. In this case +the different behaviour is caused by the compiler always issuing a Logical +Shift instruction, when it should issue a Arithmetic Shift instruction for +signed integers and a Logical Shift instructon for unsigned ones. In the +case of the short int the varable is loaded from memory into the register +with a sign extend load instruction, this makes the Logical Shift instruction +right work correctly for short ints, but not for longs. I had to examine +the assember codes output by the compiler in order to discover this. + + Here are the compiler invocation lines. + +cc -olong.shifts -DFIX_COMPILER_BUG -DINTEGER=long shifts.c + + and + +cc -oshort.shifts -DINTEGER=short shifts.c + + Experiment with the "-DFIX_COMPILER_BUG" and see what your compiler +does. + +Copyright notice:- + +(c) 1993 Christopher Sawtell. + +I assert the right to be known as the author, and owner of the +intellectual property rights of all the files in this material, +except for the quoted examples which have their individual +copyright notices. Permission is granted for onward copying, +but not modification, of this course and its use for personal +study only, provided all the copyright notices are left in the +text and are printed in full on any subsequent paper reproduction. + +-- + +----------------------------------------------------------------------+ + | NAME Christopher Sawtell | + | SMAIL 215 Ollivier's Road, Linwood, Christchurch, 8001. New Zealand.| + | EMAIL chris@gerty.equinox.gen.nz | + | PHONE +64-3-389-3200 ( gmt +13 - your discretion is requested ) | + +----------------------------------------------------------------------+ diff --git a/reference/C/CONTRIB/SAWTELL/c-lesson.6 b/reference/C/CONTRIB/SAWTELL/c-lesson.6 new file mode 100755 index 0000000..67f8852 --- /dev/null +++ b/reference/C/CONTRIB/SAWTELL/c-lesson.6 @@ -0,0 +1,331 @@ + + Lesson 5. + + The Pre-processor and Header Files. + +The pre-processor is activated by a '#' character in column one of the source +code. There are several statements vis: + +#include + +#define +#undef + +#if +#else +#endif + +#ifdef +#ifndef + +#pragma + + #include. + + In the programming examples presented in the previous lessons you will +probably have noticed that there is this statement: + +#include + +right at the start of the program text. This statement tells the pre-processor +to include the named file in the your program text. As far as the compiler is +concerned this text appears just as if you had typed it yourself! + + This is one of the more useful facilities provided by the 'C' language. +The #include statement is frequently combined with the #if construct. +In this program fragment the file "true.h" is included in your program +if the pre-processor symbol FLAG is true, and "false.h" included if FLAG +is false. + +#if ( FLAG ) +# include "true.h" +#else +# include "false.h" +#endif + +This mechanism has many uses, one of which is to provide +portability between all the 57,000 slightly different versions of unix and also +other operating systems. Another use is to be able to alter the way in which +your program behaves according to the preference of the user. + +Of course, you will be asking the question "Where is the file stored?". +Well, if the filename is delimited by the "<" and ">" characters as in the +example above the file comes from the /usr/include directory, but if the name +of the file is delimited by quotes then the file is to be found in your current +working directory. (This is not quite the whole truth as 'C' compilers allow +you to extend the search path for the include files using command line option +switches. - See your compiler manual for the whole story. ) + +So, I would like to suggest that you to have a look around the /usr/include +directory and its /sys sub-directory. You should use either your editor +in 'view' mode or the pg utility. This will ensure that you can't have an +accident and alter one of the files by mistake if you are slightly silly +and just happen to be logged on as the super-user. + +A typical file to examine is usr/include/time.h. + +It's quite small so here it is. + +/* Copyright (c) 1984 AT&T */ +/* All Rights Reserved */ + +/* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */ +/* The copyright notice above does not evidence any */ +/* actual or intended publication of such source code. */ + +#ident "@(#)/usr/include/time.h.sl 1.5 4.2 04/20/87 18195 AT&T-SF" +/* 3.0 SID # 1.2 */ +struct tm { /* see ctime(3) */ + int tm_sec; + int tm_min; + int tm_hour; + int tm_mday; + int tm_mon; + int tm_year; + int tm_wday; + int tm_yday; + int tm_isdst; +}; +extern struct tm *gmtime(), *localtime(); +extern char *ctime(), *asctime(); +int cftime(), ascftime(); +extern void tzset(); +extern long timezone, altzone; +extern int daylight; +extern char *tzname[]; + + As you can see ( forgetting about the comments and #ident ) there are three +different uses for the file. + + a) The definition of data structures and types. + b) The declaration of functions which use the data structures. + c) The declaration of of external data objects. + + These lines of code are all you need in your program in order to be able to +use, in this case, the library routine to access the clock in the computer, +but of course the paradigm applies to all programs which are created by one +programmer and used by another member of the programming team. Note that, by +proxy, or whatever, the author of the library routines has in effect become +a member of your programming team. + + You might care to write a program or two which use this header file, +and for those who are motivated it might be an idea to re-implement localtime +so that it understands Summer Time in the Southern Hemisphere. (!) + +Using another totally trivial example in order to get the idea across please +examine the hello world program printed immediately below. + +/* ------------------------------------------------------------ */ + +#ident "@(#) hw_uc.h UPPER CASE version." + +#define HELLO_MESSAGE "HELLO WORLD...\n"; + +/* ------------------------------------------------------------ */ + +#ident "@(#) Hello World" + +#include +#include HW_H + +#if !defined( HELLO_MESSAGE ) +# error "You have forgotten to define the header file name." +#endif + +char *format = "%s", + *hello = HELLO_MESSAGE; + +main() +{ + printf ( format, hello ); + } + +/* ------------------------------------------------------------ */ + +You will no doubt notice that the symbol HW_H is used instead of a header file +name. This gives us the ability to force the inclusion of any file we wish by +defining the symbol HW_H to be the desired file name. It can be done like this: + +cc -DHW_H="\"hw_uc.h\"" hello.c + +The compiler output is placed, by default, in the file a.out, so to execute it +issue the command: + +a.out + +Which, fairly obviously, produces the output: + +HELLO WORLD... + +As we are going to generate another version of the program we had better move +the executable image file to another file name: + +mv a.out hello_uc + +Now to produce the other version issue the command line: + +cc -DHW_H="\"hw_lc.h\"" hello.c; mv a.out hello_lc; hello_lc + +Which compiles the other version of the hello.c program, using this version of +the include file: + +/* ------------------------------------------------------------ */ +#ident "@(#) hw_lc.h Lower Case version." + +#define HELLO_MESSAGE "Hello World...\n"; +/* ------------------------------------------------------------ */ + +and then moves the executable image to a different file and executes it. +Note that more than one command per line can be issued to the shell by +separating the commands with the ';' delimiting character. +Here - Surprise, Surprise - is the output of the second version. + +Hello World... + +I'd like to suggest that you use your editor to cut these example programs +and the shell file below out of the mail file and have a play with them. + +/* ----------------------------------------- */ + +# @(#) Shell file to do the compilations. + +cc -o hello_uc -DHW_H="\"hw_uc.h\"" hello.c +cc -o hello_lc -DHW_H="\"hw_lc.h\"" hello.c + +/* ----------------------------------------- */ + + +#define + + This statement allows you to set up macro definitions. The word immediately +after the #define, together with its arguments, is expanded in the program +text to the whole of the rest of the line. + +#define min(a, b) ((a +#define min(a, b) ((a so you have to put +it in your program text. Once more an example to make it all clear. + + +/* ----------------------------------------- */ + +#ident "@(#) qsort-demo.c" + +#include +#include +#include + +extern void qsort (); +extern int strcmp(); /* Some compilers need this defined, most don't. */ + +char names[22][25] = /* Here are some names to sort. */ +{ + "John Nagle", "Colin Douthwaite", "Ian Lance Taylor", "Brian J. Murrell", + "Pete", "Geoff Mccaughan", "David Liebert", "Operator", "Bill Baucum", + "Victor Volkman", "Chay R Harley", "Dan Romanchik", "Larry Kollar", + "Gaston Ormazabal", "Arijit Chandra", "Kenneth Mark Hopkinson", + "Kerr Hatrick", "Tim Love", "Robert M. Juranitch", "Jeffrey Micke", + "Duong Quoc", "Jagadesh Vasudevamurthy" + }; + +#define NUMBER_OF_NAMES sizeof ( names ) / sizeof ( names[0] ) + +main() +{ + int i; + + /* + ** Print the unsorted names. + */ + + printf ( "The Unsorted Names.\n" ); + for ( i = 0; i < NUMBER_OF_NAMES; i++ ) printf ( "%s\n", names[i] ); + + /* + ** Print a prompt, and wait. + */ + + printf ( "Press RETURN to continue: " ); + fflush ( stdout ); + getchar(); + + /* + ** Now apply qsort to the arrary of character strings. + */ + + qsort (( char * ) names, NUMBER_OF_NAMES, sizeof ( *names ), strcmp ); + + assert ( names[0][0] < names[1][0] ); /* Quick check to see it's done +it. */ + + /* + ** Print the sorted names. + */ + + printf ( "The Sorted Names.\n" ); + for ( i = 0; i < NUMBER_OF_NAMES; i++ ) printf ( "%s\n", names[i] ); + } + +/* ----------------------------------------- */ + + Note very well:- + + I wanted 22 short character strings for the data items +for the demo to sort. So grep, uniq, cut, tail, and finally a tiny bit of +vi fished eminently suitable strings out of "mail.received". If your name +is not on the list, well I'm sorry, but the world is not a fair place! + + So that's how you use library routines. I chose qsort because it is +simple to use, and shows off a feature of 'C' well, that's the ability +to use a name of a function as a pointer and then execute that function +from within the called function. It's strcmp in this case. A quick look +at the compiler output is instructive. + + As is the nature of the animal, a tin-pot little program, which should +have taken all of ten minutes to get going in fact took more like two +hours. I put it down to the fact that the Fine Manual did not make it +adequately obvious that the data array acted on by qsort was the data itself. +From reading the Fine Manual I got the impression that the array acted on +was an array of pointers. You live and learn. It would be a much faster +qsort if, in fact, the sorting function sorted pointers to data instead of +the data itself. You might like to make a function qsort_p which worked in +in this way. The qsort algorithm is well documented elsewhere. + + There is just one more point to notice about using function libraries. +The 'C' compilation system will load functions from the library /lib/libc.a +as a default. All others have to be indicated to the linking loader by a +switch on the shell interactive command line. + +$ cc -o prog prog.c -L /usr/local/lib -lgdbm -lmalloc + + You might use this command line to compile and link a program which +uses both the GNU gdbm data-base manager library, which is installed in +the directory /usr/local/lib, and the enhanced malloc library. Now, there +hangs a tale! I remember having to compile a program suit off Usenet and +it just would not work properly. No error messages, no warnings, no +missing linking-loader symbols. It just "died" when I tried to run it. +After many, many hours of total frustration, I thought that I would try +linking in the enhanced malloc library. Presto! It worked. + + Note very well. + + A common misconception is the notion that having a #include +line in the source text will automagically tell the linking loader to +get the functions from the appropriate library. Remove this erroroneous +notion from your mind. It won't. The -lwhatever flag on the shell command +line which initiates execution of "cc" or "ld" is the only way to tell the +loader where to look for the required library. + + +-- + +----------------------------------------------------------------------+ + | NAME Christopher Sawtell | + | SMAIL 215 Ollivier's Road, Linwood, Christchurch, 8001. New Zealand.| + | EMAIL chris@gerty.equinox.gen.nz | + | PHONE +64-3-389-3200 ( gmt +13 - your discretion is requested ) | + +----------------------------------------------------------------------+ diff --git a/reference/C/CONTRIB/SAWTELL/c-lesson.8 b/reference/C/CONTRIB/SAWTELL/c-lesson.8 new file mode 100755 index 0000000..8e2bff9 --- /dev/null +++ b/reference/C/CONTRIB/SAWTELL/c-lesson.8 @@ -0,0 +1,502 @@ + + Lesson 7. + + De-bugging Strategies. + + >>>>>>>> Proper Preparation Prevents Piss-Poor Performance. <<<<<<<< + + This lesson is really a essay about how to go about writing programs. + + I know that by far the best way to greatly reduce the amount of effort +required to get a program going properly is to avoid making mistakes in the +first palace! Now this might seem to be stating the absolute obvious, and it +is but after looking at many programs it would seem that there is a very +definite need to say it. + + So how does one go about reducing the probability of making mistakes? + + There are many strategies, and over the years I have evolved my own set. + I have found that some of the most important are: + + 1) Document what you are going to do before yes BEFORE you write any code. + Set up the source files for the section of the program you are going to + write and put some lines of explanation as to what you intend to do in + this file. Be as precise as you can, but don't go into the detail of + explaining in English, or your First Language, exactly what every + statement does. + + 2) Make sure that you keep each file as small as is sensible. Some program + authors say that one should put only one function in a file. It's my + personal opinion that this is going a little bit over the top, but + certainly you should not have more than one logical activity in a source + file. It's easier to find a needle in a tiny haystack than in a big one! + + 3) Always use names for the objects in your program which are fully + descriptive, or at the very least are meaningful nmemonics. Put yourself + in the position of some poor soul who - a couple of years later, after you + have long finished with the project, and left the country - has been given + the task of adding a small feature to your exquisite program. Now in the + rush to get your masterpiece finished you decided to use variable names + like "a4" and "isb51" simply so that you can get the line typed a + fraction of a second faster than if you used something like + "customer_address[POST_CODE]" and "input_status_block[LOW_FUEL_TANK_#3]. + The difference in ease of understanding is obvious, isn't it? However + judging by some programs which I have seen published in both magazines and + in the public domain program sources, the point has still to be made. + + 4) ALWAYS take great care with the layout of your code. + It's my opinion that the opening brace of ALL program structures should + be on a new line. Also if you put them in the leftmost column for structs, + enums, and initialised tables, as well as functions, then the + 'find function' keystrokes ( "[[" and "]]" ) in vi will find them as well + as the functions themselves. Make sure you have the "showmatch" facility + in vi turned on. ( And watch the cursor jump when you enter the + right hand brace, bracket, or parenthesis. ) + + 5) Try as hard as you can to have as few global variables as possible. + Some people say never have any globals. This is perhaps a bit too + severe but global variables are a clearly documented source of + programming errors. If it's impossible to perform a logical activity + in an efficient way without having a global or two, then confine + the scope of the globals to just the one file by marking the defining + declaration "static". This stops the compiler producing a symbol which + the linking loader will make available to all the files in your source. + + 6) Never EVER put 'magic numbers' in you source code. Always define constants + in a header file with #define lines or enum statements. + + Here is an example:- + + +/* ----------------------------------------- */ + +#include + +enum status_input_names +{ + radiator_temperature, + oil_temperature, + fuel_pressure, + energy_output, + revolutions_per_minute + }; + +char *stats[] = +{ + "radiator_temperature", + "oil_temperature", + "fuel_pressure", + "energy_output", + "revolutions_per_minute" + }; + +#define NUMBER_OF_INPUTS ( sizeof ( stats ) / sizeof ( stats[0])) + +main() +{ + enum status_input_names name; + + printf ( "Number of Inputs is: %d\n", NUMBER_OF_INPUTS ); + for ( name = radiator_temperature; name < NUMBER_OF_INPUTS; name++) + { + printf ( "\n%s", stats[ name ] ); + } + printf ( "\n\n" ); + } + +/* ----------------------------------------- */ + + Note that as a side effect we have available the meaningful symbols + radiator_temperature etc. as indices into the array of status input names + and the symbol NUMBER_OF_INPUTS available for use as a terminator in the + 'for' loop. This is quite legal because sizeof is a pseudo-function and the + value is evaluated at the time of compilation and not when the program is + executed. This means that the result of the division in the macro is + calculated at the time of compilation and this result is used as a literal + in the 'for' loop. No division takes place each time the loop is executed. + + To illustrate the point I would like to tell you a little story which is + fictitious, but which has a ring of truth about it. + Your employer has just landed what seems to be a lucrative contract with + an inventor of a completely new type of engine. We are assured that after + initial proving trials one of the larger Japanese motor manufactures is + going to come across with umpteen millions to complete the development of + the design. You are told to write a program which has to be a simple and + straightforward exercise in order to do the job as cheaply as possible. + Now, the customer - a some-what impulsive type - realises that his + engine is not being monitored closely enough when it starts to rapidly + dis-assemble itself under high speed and heavy load. You have to add a + few extra parameters to the monitoring program by yesterday morning! + You just add the extra parameters into the enumand the array of pointers + to the character strings. So: + +enum status_input_names +{ radiator_temperature, + radiator_pressure, + fuel_temperature, + fuel_pressure, + oil_temperature, + oil_pressure, + exhaust_manifold_temperature + }; + + Let's continue the story about the Japanese purchase. Mr. Honda ( jun ) has + come across with the money and the result is that you are now a team leader + in the software section of Honda Software ( YourCountry ) Ltd. The project of + which you are now leader is to completely rewrite your monitoring program and + add a whole lot of extra channels as well as to make the printouts much more + readable so that your cheap, cheerful, and aesthetic-free program can be sold + as the "Ultimate Engine Monitoring Package" from the now world famous Honda + Real-time Software Systems. You set to work, Honda et. al. imagine that there + is going to be a complete redesign of the software at a cost of many million + Yen. You being an ingenious type have written the code so that it is easy to + enhance. + + The new features required are that the printouts have to be printed with the + units of measure appended to the values which have to scaled and processed so + that the number printed is a real physical value instead of the previous + arrangement where the raw transducer output was just dumped onto a screen. + + What do you have to do? + + Thinking along the line of "Get the Data arranged correctly first". + You take you old code and expand it so that all the items of information + required for each channel are collected into a struct. + +enum status_input_names +{ + radiator_temperature, + radiator_pressure, + fuel_temperature, + fuel_pressure, + oil_temperature, + oil_pressure, + exhaust_manifold_temperature, + power_output, + torque + }; + +typedef struct channel +{ + char *name; /* Channel Name to be displayed on screen. */ + int nx; /* position of name on screen x co-ordinate. +*/ + int ny; /* ditto for y */ + int unit_of_measure; /* index into units of measure array */ + char value; /* raw datum value from 8 bit ADC */ + char lower_limit; /* For alarms. */ + char upper_limit; + float processed_value; /* The number to go on screen. */ + float offset; + float scale_factor; + int vx; /* Position of value on screen. */ + int vy; + }CHANNEL; + +enum units_of_measure { kPa, degC, kW, rpm, Volts, Amps, Newtons }; + +char *units { "kPa", "degC", "kW", "rpm", "Volts", "Amps", "Newtons" }; + +CHANNEL data [] = +{ + { "radiator temperature", + { "radiator pressure", + { "fuel temperature", + { "fuel pressure", + { "oil temperature", + { "oil pressure", + { "exhaust manifold temperature", + { "power output", + { "torque", + }; + +#define NUMBER_OF_INPUTS sizeof (data ) / sizeof ( data[0] ) + +Now the lesson preparation is to find the single little bug in the above +program fragment, to finish the initialisation of the data array of type +CHANNEL and to have a bit of a crack at creating a screen layout +program to display its contents. Hint: Use printf(); +( Leave all the values which originate from the real world as zero. ) + + + Here are some more tips for young players. + + 1) Don't get confused between the logical equality operator, + + == + + and the assignment to a variable operator. + + = + + This is probably the most frequent mistake made by 'C' beginners, and + has the great disadvantage that, under most circumstances, the compiler + will quite happily accept your mistake. + + 2) Make sure that you are aware of the difference between the logical + and bit operators. + + && This is the logical AND function. + || This is the logical OR function. + The result is ALWAYS either a 0 or a 1. + + & This is the bitwise AND function used for masks etc. + The result is expressed in all the bits of the word. + + 3) Similarly to 2 be aware of the difference between the logical + complementation and the bitwise one's complement operators. + + ! This is the logical NOT operator. + ~ This is the bitwise ones complement op. + + Some further explanation is required. In deference to machine efficiency a + LOGICAL variable is said to be true when it is non-zero. So let's set a + variable to be TRUE. + + 00000000000000000000000000000001 A word representing TRUE. + Now let's do a logical NOT !. + 00000000000000000000000000000000 There is a all zero word, a FALSE. + + 00000000000000000000000000000001 That word again. TRUE. + Now for a bitwise complement ~. + 11111111111111111111111111111110 Now look we've got a word which is + non-zero, still TRUE. + + Is this what you intended? + + 4) It is very easy to fall into the hole of getting the + '{' & '}'; '[' & ']'; '(' & ')'; symbol pairs all messed up and the + computer thinks that the block structure is quite different from that + which you intend. Make sure that you use an editor which tells you the + matching symbol. The UNIX editor vi does this provided that you turn + on the option. Also take great care with your layout so that the block + structure is absolutely obvious, and whatever style you choose do take + care to stick by it throughout the whole of the project. + A personal layout paradigm is like this: + + Example 1. + +function_type function_name ( a, b ) +type a; +type b; +{ + type variable_one, variable_two; + + if ( logical_expression ) + { + variable_one = A_DEFINED_CONSTANT; + if ( !return_value = some_function_or_other ( a, + variable_one, + &variable_two + ) + ) + { + error ( "function_name" ); + exit ( FAILURE ); + } + else + { + return ( return_value + variable_two ); + } + } /* End of "if ( logical_expression )" block */ + } /* End of function */ + + This layout is easy to do using vi with this initialisation script + in either the environment variable EXINIT or the file ${HOME}/.exrc:- + +set showmode autoindent autowrite tabstop=2 shiftwidth=2 showmatch wm=1 + + Example 2. + +void printUandG() +{ + char *format = +"\n\ + User is: %s\n\ + Group is: %s\n\n\ + Effective User is: %s\n\ +Effective Group is: %s\n\n"; + + ( void ) fprintf ( tty, + format, + passwd_p->pw_name, + group_p->gr_name, + epasswd_p->pw_name, + egroup_p->gr_name + ); + } + + Notice how it is possible to split up format statements with a '\' as + the last character on the line, and that it is convenient to arrange + for a nice output format without having to count the + field widths. Note however that when using this technique that the '\' + character MUST be the VERY LAST one on the line. Not even a space may + follow it! + + In summary I *ALWAYS* put the opening brace on a new line, set the tabs + so that the indentation is just two spaces, ( use more and you very quickly + run out of "line", especially on an eighty column screen ). If a statement + is too long to fit on a line I break the line up with the arguments set out + one to a line and I then the indentation rule to the parentheses "()" + as well. Sample immediately above. Probably as a hang-over from a particular + pretty printing program which reset the indentation position after the + printing of the closing brace "}", I am in the habit of doing it as well. + Long "if" and "for" statements get broken up in the same way. This is + an example of it all. The fragment of code is taken from a curses oriented + data input function. + + /* + ** Put all the cursor positions to zero. + */ + + for ( i = 0; + s[i].element_name != ( char *) NULL && + s[i].element_value != ( char *) NULL; + i = ( s[i].dependent_function == NULL ) + ? s[i].next : s[i].dependent_next + ) + { /* Note that it is the brace and NOT the */ + /* "for" which moves the indentation level. */ + s[i].cursor_position = 0; + } + + /* + ** Go to start of list and hop over any constants. + */ + + for ( i = edit_mode = current_element = 0; + s[i].element_value == ( char *) NULL ; + current_element = i = s[i].next + ) continue; /* Note EMPTY statement. */ + + /* + ** Loop through the elements, stopping at end of table marker, + ** which is an element with neither a pointer to an element_name nor + ** one to a element_value. + */ + + while ( s[i].element_name != ( char *) NULL && + s[i].element_value != ( char *) NULL + ) + { + int c; /* Varable which holds the character from the keyboard. */ + + /* + ** Et Cetera for many lines. + */ + + } + + Note the commenting style. The lefthand comments provide a general +overview of what is happening and the righthand ones a more detailed view. +The double stars make a good marker so it is easy to separate the code and +the comments at a glance. + + The null statement. + + You should be aware that the ";" on its own is translated by the compiler +as a no-operation statement. The usefullness of this is that you can do +little things, such as counting up a list of objects, or positioning a pointer +entirely within a "for" or "while" statement. ( See example above ). +There is, as always, a flip side. It is HORRIBLY EASY to put a ";" at the +end of the line after the closing right parenthesis - after all you do just +that for function calls! The suggestion is to both mark deliberate null +statements with a comment and to use the statement "continue;". Using +the assert macro will pick up these errors at run time. + + The assert macro. + + Refer to the Programmers Reference Manual section 3X and find the +documentation on this most useful tool. + + As usual an example is by far the best wasy to explain it. + +/* ----------------------------------------- */ + +#ident "@(#) assert-demo.c" + +#include +#include + +#define TOP_ROW 10 +#define TOP_COL 10 + +main() +{ + int row, col; + + for ( row = 1; row <= TOP_ROW; row++); + { + assert ( row <= TOP_ROW ); + for ( col = 1; col <= TOP_COL; col++ ) + { + assert ( col <= TOP_COL ); + printf ( "%4d", row * col ); + } + printf ( "\n" ); + } + } + +/* ----------------------------------------- */ + + Which produces the output:- + +Assertion failed: row <= TOP_ROW , file assert-demo.c, line 15 +ABORT instruction (core dumped) + + It does this because the varable "row" is incremented +to one greater than The value of TOP_ROW. + + Note two things: + + 1) The sense of the logical condition. The assert is asserted + as soon as the result of the logical condition is FALSE. + Have a look at the file /usr/include/assert. + Where is the ";" being used as an empty program statement? + + 2) The unix operating system has dumped out an image of the executing + program for examination using a symbolic debugger. Have a play with + "sdb" in preparation for the lesson which deals with it in more + detail. + + Lets remove the errant semi-colon, re-compile and re-run the program. + + 1 2 3 4 5 6 7 8 9 10 + 2 4 6 8 10 12 14 16 18 20 + 3 6 9 12 15 18 21 24 27 30 + 4 8 12 16 20 24 28 32 36 40 + 5 10 15 20 25 30 35 40 45 50 + 6 12 18 24 30 36 42 48 54 60 + 7 14 21 28 35 42 49 56 63 70 + 8 16 24 32 40 48 56 64 72 80 + 9 18 27 36 45 54 63 72 81 90 + 10 20 30 40 50 60 70 80 90 100 + + Here's the ten times multiplication table, for you to give to to +the nearest primary-school child! + + I would agree that it is not possible to compare the value of a program +layout with a real work of fine art such as a John Constable painting or +a Michaelangelo statue, I do think a well laid out and literate example of +programming is not only much easier to read and understand, but also it +does have a certain aesthetic appeal. + +Copyright notice:- + +(c) 1993 Christopher Sawtell. + +I assert the right to be known as the author, and owner of the +intellectual property rights of all the files in this material, +except for the quoted examples which have their individual +copyright notices. Permission is granted for onward copying, +but not modification, of this course and its use for personal +study only, provided all the copyright notices are left in the +text and are printed in full on any subsequent paper reproduction. + +-- + +----------------------------------------------------------------------+ + | NAME Christopher Sawtell | + | SMAIL 215 Ollivier's Road, Linwood, Christchurch, 8001. New Zealand.| + | EMAIL chris@gerty.equinox.gen.nz | + | PHONE +64-3-389-3200 ( gmt +13 - your discretion is requested ) | + +----------------------------------------------------------------------+ diff --git a/reference/C/CONTRIB/SAWTELL/c-lesson.9 b/reference/C/CONTRIB/SAWTELL/c-lesson.9 new file mode 100755 index 0000000..5d03e3b --- /dev/null +++ b/reference/C/CONTRIB/SAWTELL/c-lesson.9 @@ -0,0 +1,433 @@ + + Lesson 8. + + This lesson and the following one will examine how to use the program +structure - as opposed to data structure - reserved words. + + Lets start with the looping structures: + + do repeated_statement while ( logical_expression ); + + repeated_statement, which may be a block of code, will be executed +repetitively until the logical_expression, becomes false. If you have been +exposed to ( corrupted by? ) another language remember that there is no +`until' test at the end of a loop. Note that the repeated_statement is always +executed once irrespective of the state of the logical_expression. + + while ( logical_expression ) repeated_statement; + + repeated_statement is executed repetitively while the logical_expression +is true. Once again statement may be a block of code. Note that if the +logical_expression evaluates to FALSE then the repeated_statement is NEVER +executed. + + Associated with the looping structures are the control words: + + break; + continue; + + break; allows you to leave a loop in the middle of a block, and + continue; allows you to re-start it from the top. + + Finally we must not forget the most common and useful looping construct: + + for ( initialising statement; logical_expression; incremental_statement ) + repeated_statement; + + Some further explanation is needed. The initialising statement is +executed once, but to allow for the need to initialise several separate +variables the assignment statements may be separated by commas. The +logical_expression must be true for the loop to run, and the +incremental_statement is executed once each time the loop is run. +The for statement is completely general and may, for example, be used to +manipulate a set of pointers to operate on a linked list. + +Some examples. + + A do loop program. + +#ident "@(#) do_demo.c - An example of the do loop" + +#include + +main() +{ + char character; + + character = 'a'; + + do printf ( "%c", character ); while ( character++ < 'z' ); + printf ( "\n" ); + } + + Fairly obviously it prints: + +abcdefghijklmnopqrstuvwxyz + + A while loop example. + +#ident "@(#) while_demo.c - An example of the while loop" + +#include + +main() +{ + char character; + + character = 'a'; + + while ( character <= 'z' ) printf ( "%c", character++ ); + printf ( "\n" ); + } + + Its output is exactly the same as the previous example: + +abcdefghijklmnopqrstuvwxyz + + In this totally trivial case it is irrelevant which program structure + you use, however you should note that in the `do' program structure the + repeated statement is always executed at least once. + A for loop example. + + The `for' looping structure. + +#ident "@(#) for_demo.c - An example of the for loop" + +#include + +main() +{ + char character; + + for ( character = 'a'; character <= 'z' ; character++ ) + { + printf ( "%c", character ); + } + printf ( "\n" ); + } + + Surprise, Surprise! + +abcdefghijklmnopqrstuvwxyz + + You should be aware that in all the looping program structures, the +repeated statement can be a null statement ( either just a `;' or the +reserved word `continue;' ). This means that it is possible to - for +example - position a pointer, or count up some items of something or other. +It isn't particularly easy to think up a trivial little program which +demonstrates this concept, however the two `for' loops give some indication +of the idea. + +#ident "@(#) pointer_demo.c - Pointer operations with the for loop" + +#include + +main() +{ + char character, *character_pointer, alphabets [ 53 ]; + + for ( character = 'a', character_pointer = alphabets; /* Start conditions */ + character <= 'z'; /* Run while true */ + *character_pointer++ = character++ /* All the work */ + )TRUE continue; + + for ( character = 'A'; /* character_pointer is at the right place already */ + character <= 'Z'; + *character_pointer++ = character++ + ) continue; + + *character_pointer = (char) '\000'; /* NULL character to terminate string. */ + + printf ( "%s\n\n", alphabets ); + } + + Another Surprise! + +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ + + So much for the looping structures provided by the `C' language. The +other main structures required to program a computer are the ones which +alter the program flow. These are the switch, and the if and its extension +the if ... else combination. More demo programs are much the best way of +getting the message across to you, so here they are, first the if construct. + +#ident "if_demo.c" + +#include + +main(argc, argv) +int argc; +char **argv; +{ + if ( argc > 1 ) printf ( "You have initiated execution with arguments."}; + } + + And the if ... else demo. + +#ident "if_else_demo.c" +/* +** The Language #define could go in the compiler invocation line if desired. +*/ + +#define ENGLISH + +#include + +/* +** The message and text fragments output by the program. +*/ + +char *messages[] = +{ +#if defined( ENGLISH ) +#ident "@(#)ENGLISH Version" + "\nUsage: if_else_demo \n\n", + "The first argument is ", + "the second", + "equal to ", + "bigger than ", + "smaller than " +#endif + +#if defined( FRANCAIS ) +#ident "@(#)FRENCH Version" + + put the French translation in here so that we are ready to export to + French speaking Countries. I'd be grateful if a French speaker could + make the translation for me. + +#endif + }; + +/* +** Meaningful words defined to constants +*/ + +#define USAGE 0 +#define FIRST 1 +#define SECOND 2 +#define EQUAL 3 +#define BIGGER 4 +#define SMALLER 5 + +#define SUCCESS 0 +#define FAILURE 1 + +/* +** We need this more than once so it can be put in a function. +*/ + +void usage() +{ + printf ( messages[USAGE]); + exit ( FAILURE ); + } + +/* +** Main program function starts here. ( At the top of a page no less! ) +*/ + +int main ( argc, argv ) +int argc; +char **argv; +{ + int message_index; + double i, j, strtod(); + char *ptr; + + if ( argc != 3 ) usage(); /* have we been given the right */ + /* number of arguments. */ + i = strtod ( argv[1], &ptr); /* Convert to a double float. */ + if ( ptr == argv[1] ) usage(); /* Successful conversion? */ + j = strtod ( argv[2], &ptr); /* Convert to a double float. */ + if ( ptr == argv[2] ) usage(); /* Successful conversion? */ + +/* +** This statement uses the "ternary conditional assignment" language +** construction to assign the value required to the message indexing variable. +** Note that this concept is efficient in both the generation of machine code +** output ( compile the program with a -S switch and have a look ) and in the +** ease with which it can be understood. The assignment is obvious instead of +** being buried under a litter of `if' and `else' keywords. +*/ + + message_index = ( i == j ) ? EQUAL : ( i > j ) ? BIGGER : SMALLER; + +/* +** Now print the message. +*/ + + (void) printf ( "\n%s%s%s\n\n", /* Format string specifying 3 strings. */ + messages[ FIRST ], /* Address of string. */ + messages[ message_index ], /* ditto. */ + messages[ SECOND ] /* ditto. */ + ); + return ( SUCCESS ); + } + + Well as you can no doubt gather it simply compares two numbers on the +command line and ejects a little message depending on the relative magnitude +of the numbers. In the UNIX tradition the help message is perhaps somewhat +terse, but it serves the purpose of getting you - the student - to think +about the importance of creating programs which always cope with nonsensical +input in a civilised way. Here are the lines of output. + +Usage: if_else_demo + +The first argument is equal to the second + +The first argument is smaller than the second + +The first argument is bigger than the second + + Now that the international community is shrinking with vastly improved +telecommunications, it is perhaps a good idea to think carefully about +creating programs which can talk in many languages to the users. The method +of choice is - I believe - that presented above. The #if defined( LANGUAGE ) +gives us an easy method of changing the source code to suit the new sales +area. Another possibility is to put all the text output needed from a program +into a file. The file would have to have a defined layout and some consistent +way of `getting at' the message strings. + + From a commercial point of view this may or may not be a good business plan. +Quite definitely it is an absolute no no to scatter a mass of string literals +containing the messages and message fragments all over your program script. + + There are two more methods of altering the program flow. + + 1 ) The goto a label. + 2 ) The setjump / longjmp library routines. + + The concept of the go to a label construction has had reams of literary +verbiage written about it and this author does not intend to add to the pile. +Suffice it to say that a goto is a necessary language construct. There are a +few situations which require the language to have ( in practice ) some form of +unconditional jump. Treat this statement with great caution if you wish your +code to be readable by others. An example of legitimate use. + + for ( a = 0; a < MATRIX_SIZE; a++ ) + { + for ( b = 0; b < MATRIX_SIZE; b++ ) + { + if ( process ( matrix, a, b )) goto bad_matrix; + } + } + return ( OK ); + +bad_matrix: + + perror ( progname, "The data in the matrix seems to have been corrupted" ); + return ( BAD ); + + This is one of the very few "legitimate" uses of goto, as there is no +"break_to_outer_loop" in `C'. Note that some compilers complain if the label +is not immediately followed by a statement. If your compiler is one of these +naughty ones, you can put either a `;' or a pair of braces `{}' after the +`:' as a null statement. + + An example of a program package which makes extensive use of the goto is the +rz and sz modem communications protocol implementation by Chuck Forsberg of +Omen Technology. You should download it and study the code, but do remember +that the proof of the pudding argument must apply as the rz & sz system has +become extremely popular in its application because it works so well. + + The other method of changing program flow is the setjump and longjmp pair of +library functions. The idea is to provide a method of recovery from errors +which might be detected anywhere within a large program - perhaps a compiler, +interpreter or large data acquisition system. Here is the trivial example: + +#ident "set_jmp_demo.c" + +#include +#include + +jmp_buf save; + +main() +{ + char c; + + for ( ;; ) /* This is how you set up a continuous loop. +*/ + { + switch ( setjmp( save )) + { +case 0: + printf ( "We get a zero returned from setjmp on setup.\n\n"); + break; /* This is the result from setting up. */ + +case 1: + printf ( "NORMAL PROGRAM OPERATION\n\n" ); + break; + +case 2: + printf ( "WARNING\n\n" ); + break; + +case 3: + printf ( "FATAL ERROR PROGRAM TERMINATED\n\nReally Terminate? y/n: " ); + fflush ( stdout ); + scanf ( "%1s", &c ); + c = tolower ( c ); + if ( c == 'y' ) return ( 1 ); + printf ( "\n" ); + break; + +default: + printf ( "Should never return here.\n" ); + break; + } + process (); + } + } + +process () +{ + int i; + + printf ( "Input a number to simulate an error condition: " ); + fflush ( stdout ); + scanf ( "%d", &i ); + i %= 3; + i++; /* So that we call longjmp with 0 < i < 4 */ + longjmp ( save, i); + } + + Although in this silly little demo the call to longjmp is in the same file +as the call to setjmp, this does not have to be the case, and in the practical +situation the call to longjmp will be a long way from the call to setjmp. The +mechanism is that setjmp saves the entire state of the computer's CPU in a +buffer declared in the jmp_buf save; statement and longjmp restores it exactly +with the exception of the register which carries the return value from longjmp. +This value is the same as the second argument in the longjmp call - i in our +little demo. This means, of course, that the stack and frame pointer registers +are reset to the old values and all the local variables being used at the time +of the longjmp call are going to be lost forever. One consequence of this is +that any pointer to memory allocated from the heap will also be lost, and +you will be unable to access the data stored in the buffer. This is what the +jargonauts call "memory leakage", and is really very difficult bug to find. +Your program runs out of dynamic memory long before it should. Take care. +So you have to keep a record of the buffers' addresses and free them +before the call to longjmp. + +More details later on when we learn about the heap memory allocation routines. + +Copyright notice:- + +(c) 1993 Christopher Sawtell. + +I assert the right to be known as the author, and owner of the +intellectual property rights of all the files in this material, +except for the quoted examples which have their individual +copyright notices. Permission is granted for onward copying, +but not modification, of this course and its use for personal +study only, provided all the copyright notices are left in the +text and are printed in full on any subsequent paper reproduction. + +-- + +----------------------------------------------------------------------+ + | NAME Christopher Sawtell | + | SMAIL 215 Ollivier's Road, Linwood, Christchurch, 8001. New Zealand.| + | EMAIL chris@gerty.equinox.gen.nz | + | PHONE +64-3-389-3200 ( gmt +13 - your discretion is requested ) | + +----------------------------------------------------------------------+ diff --git a/reference/C/CONTRIB/SAWTELL/intro.html b/reference/C/CONTRIB/SAWTELL/intro.html new file mode 100644 index 0000000..3278d20 --- /dev/null +++ b/reference/C/CONTRIB/SAWTELL/intro.html @@ -0,0 +1,24 @@ +C Lesson by Chris Sawtell +

C Lesson by Chris Sawtell

+This copy was taken in May 94. The latest version is available +by +clicking here +
+
+ Introduction +
+ History +
+ Data Storage. +
+ Arrays & Pointers +
+ Operators +
+ Pre-processor +
+ Libraries +
+ Debugging +
+ Structure diff --git a/reference/C/CONTRIB/SNIP/2dlife.c b/reference/C/CONTRIB/SNIP/2dlife.c new file mode 100755 index 0000000..aedee30 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/2dlife.c @@ -0,0 +1,111 @@ +/* +** A quick "life" (2-d cellular automaton) implementation done in Turbo C 2.0 +** on the spur-of-the-moment by Jonathan Guthrie 9/20/1992 and donated to the +** public domain. +** +** In keeping with the guidelines of the C_ECHO, this program has been tested, +** and does seem to operate properly. +*/ + +#include +#include +#include +#include + +#ifndef random + #define random(num) (int)(((long)rand()*(num))/RAND_MAX) +#endif + +/* +** From VIDPORT.C, also in SNIPPETS +*/ + +void GotoXY(int col, int row); +void ClrScrn(int vattrib); + +#ifndef randomize + #define randomize() srand(((unsigned int)time(NULL))|1) +#endif + +#define ROWS 24 +#define COLS 80 +#define GENERATIONS 10 + +int civ1[ROWS][COLS], civ2[ROWS][COLS]; + +void update_generation(int old[ROWS][COLS], int new[ROWS][COLS]) +{ + int i, j, count; + + for (i = 0; i < ROWS; ++i) + { + for (j = 0; j < COLS; ++j) + { + count = old[(i + ROWS - 1) % ROWS][(j + COLS - 1) % COLS] + + old[(i + ROWS - 1) % ROWS][j] + + old[(i + ROWS - 1) % ROWS][(j + 1) % COLS] + + old[i][(j + COLS - 1) % COLS] + + old[i][(j + 1) % COLS] + + old[(i + 1) % ROWS][(j + COLS - 1) % COLS] + + old[(i + 1) % ROWS][j] + + old[(i + 1) % ROWS][(j + 1) % COLS]; + + switch(count) + { + case 0: + case 1: + case 4: + case 5: + case 6: + case 7: + case 8: + new[i][j] = 0; + break; + + case 2: + new[i][j] = old[i][j]; + break; + + case 3: + new[i][j] = 1; + break; + } + + GotoXY(j+1, i+1); + putch(new[i][j] ? '*' : ' '); + } + } +} + + +void initialize(void) +{ + int i, j; + + randomize(); + ClrScrn(7); + + for (i = 0; i < ROWS; ++i) + { + for (j = 0; j < COLS; ++j) + { + civ1[i][j] = random(2); + GotoXY(j+1, i+1); + putch(civ1[i][j] ? '*' : ' '); + } + } +} + + +int main(void) +{ + int i; + + initialize(); + for (i = 0; i < GENERATIONS; ++i) + { + update_generation(civ1, civ2); + update_generation(civ2, civ1); + } + return EXIT_SUCCESS; +} diff --git a/reference/C/CONTRIB/SNIP/8087_sav.asm b/reference/C/CONTRIB/SNIP/8087_sav.asm new file mode 100755 index 0000000..603303f --- /dev/null +++ b/reference/C/CONTRIB/SNIP/8087_sav.asm @@ -0,0 +1,73 @@ +; By: Jeffrey Nonken + + page 60,132 + .286 + +_text segment byte public 'code' +_text ends +_data segment word public 'data' +_data ends +const segment word public 'const' +const ends +_bss segment word public 'bss' +_bss ends +dgroup group const, _bss, _data + assume cs: _text, ds: nothing + +_data segment word public 'data' + even +env_8087 dw 47 dup (?) +norm_8087 dw 177fh +_data ends + +_text segment byte public 'code' +; +; This code saves the 80x87 enviroment and sets up our own. First, this +; assumes you are running an 80287; the 8087 may require more FWAIT +; operations. Second, I decided that I didn't want to handle exceptions, so +; I simply disabled them. That means that if the 80x87 gets an invalid result +; (such as divide-by-zero) the 80x87 will continue to run and will produce +; invalid results until the end of your current calculation. Anything that +; depends on the results will, of course, also be invalid. If you want +; exceptions to be handled, get documentation for the 80x87 and you will +; see how to set norm_8087 (above) to suit your needs. If you are running +; an 8087 and don't know where to put FWAIT instructions, you can always +; add one after each floating-point instruction. NOTE: FWAIT is synonymous +; to WAIT. They are the same instruction. +; +; This was written for TURBO C and will also work with MSC. It should work +; with any programming language with no more than minor changes in the +; label names or the interface. Consult your compiler manual for more detail. +; I wrote this so it would work with either the tiny or small models. +; Actually, it will probably work with any of the models. You should be +; able to assemble this with MASM and link it right in. +; +; extern save_8087(); +; extern restore_8087(); +; + public _save_8087 +_save_8087 proc near + cli ; no interruptions! + lea bx,dgroup:env_8087 ; point to save area + fwait ; make sure processor is ready + fnsave [bx] ; save the 8087 environment + lea bx,dgroup:norm_8087 ; point to our new 8087 setup + mov ax,[bx] ; get it + fldcw [bx] ; set it + fwait + sti ; restore interrupts + ret +_save_8087 endp + + public _restore_8087 +_restore_8087 proc near + cli ; no interruptions! + lea bx,dgroup:env_8087 ; point to saved 8087 stuff + frstor [bx] ; restore the 8087 environment + sti ; restore interrupts + ret +_restore_8087 endp + +_text ends + + end diff --git a/reference/C/CONTRIB/SNIP/HEADER.html b/reference/C/CONTRIB/SNIP/HEADER.html new file mode 100644 index 0000000..099dc18 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/HEADER.html @@ -0,0 +1,14 @@ +Snippets +

Snippets

+ +This is Bob Stouts compilation of public domain C programs. +A large number of these +programs are not portable as they require DOS. That aside, this is a good +source of examples and utilities. +

+ +This copy was taken in Jan '95. If you want the latest, +click here. +


+ + diff --git a/reference/C/CONTRIB/SNIP/Makefile.am b/reference/C/CONTRIB/SNIP/Makefile.am new file mode 100644 index 0000000..e5c6fc9 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/Makefile.am @@ -0,0 +1,9 @@ +EXTRA_DIST = $(wildcard *.html) $(wildcard *.c) $(wildcard *.h) $(wildcard *.asm) $(wildcard *.txt) \ + 8087_sav.asm HEADER.html c_lines.awk except.doc file_id.diz make.ini match.doc myio.cpp \ + myio.mak myiodemo.cpp myline.cpp mystream.cpp pdn.lst read.me resource.lst rg_qsort.c1 \ + rg_qsort.c2 snippets._c_ snippets.ndx snippets.txt snippets.wc storage.typ str.cpp str.doc + +docs_DATA = $(EXTRA_DIST) + +docsdir = $(kde_htmldir)/en/kdevelop/$(subdir) + diff --git a/reference/C/CONTRIB/SNIP/Makefile.in b/reference/C/CONTRIB/SNIP/Makefile.in new file mode 100644 index 0000000..dc3dd1b --- /dev/null +++ b/reference/C/CONTRIB/SNIP/Makefile.in @@ -0,0 +1,415 @@ +# KDE tags expanded automatically by am_edit - $Revision: 1.2 $ +# Makefile.in generated automatically by automake 1.5 from Makefile.am. + +# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +# Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = ../../../.. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_HEADER = $(INSTALL_DATA) +transform = @program_transform_name@ +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_alias = @build_alias@ +build_triplet = @build@ +host_alias = @host_alias@ +host_triplet = @host@ +target_alias = @target_alias@ +target_triplet = @target@ +AMTAR = @AMTAR@ +ARTSCCONFIG = @ARTSCCONFIG@ +AS = @AS@ +AUTODIRS = @AUTODIRS@ +AWK = @AWK@ +CC = @CC@ +CONF_FILES = @CONF_FILES@ +CPP = @CPP@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +DCOPIDL = @DCOPIDL@ +DCOPIDL2CPP = @DCOPIDL2CPP@ +DCOP_DEPENDENCIES = @DCOP_DEPENDENCIES@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DPMSINC = @DPMSINC@ +DPMSLIB = @DPMSLIB@ +EXEEXT = @EXEEXT@ +GCJ = @GCJ@ +GCJFLAGS = @GCJFLAGS@ +GLINC = @GLINC@ +GLLIB = @GLLIB@ +GMSGFMT = @GMSGFMT@ +IDL = @IDL@ +IDL_DEPENDENCIES = @IDL_DEPENDENCIES@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +JAR = @JAR@ +JAVAC = @JAVAC@ +JAVAH = @JAVAH@ +JVMLIBS = @JVMLIBS@ +KDECONFIG = @KDECONFIG@ +KDE_CXXFLAGS = @KDE_CXXFLAGS@ +KDE_EXTRA_RPATH = @KDE_EXTRA_RPATH@ +KDE_INCLUDES = @KDE_INCLUDES@ +KDE_LDFLAGS = @KDE_LDFLAGS@ +KDE_PLUGIN = @KDE_PLUGIN@ +KDE_RPATH = @KDE_RPATH@ +KDE_USE_CLOSURE_FALSE = @KDE_USE_CLOSURE_FALSE@ +KDE_USE_CLOSURE_TRUE = @KDE_USE_CLOSURE_TRUE@ +KDE_USE_FINAL_FALSE = @KDE_USE_FINAL_FALSE@ +KDE_USE_FINAL_TRUE = @KDE_USE_FINAL_TRUE@ +KDE_XSL_STYLESHEET = @KDE_XSL_STYLESHEET@ +LIBCOMPAT = @LIBCOMPAT@ +LIBCRYPT = @LIBCRYPT@ +LIBDL = @LIBDL@ +LIBGEN = @LIBGEN@ +LIBJPEG = @LIBJPEG@ +LIBMICO = @LIBMICO@ +LIBOBJS = @LIBOBJS@ +LIBPNG = @LIBPNG@ +LIBPTHREAD = @LIBPTHREAD@ +LIBPYTHON = @LIBPYTHON@ +LIBQIMGIO = @LIBQIMGIO@ +LIBRESOLV = @LIBRESOLV@ +LIBSHADOW = @LIBSHADOW@ +LIBSM = @LIBSM@ +LIBSOCKET = @LIBSOCKET@ +LIBTIFF = @LIBTIFF@ +LIBTOOL = @LIBTOOL@ +LIBUCB = @LIBUCB@ +LIBUTIL = @LIBUTIL@ +LIBXINERAMA = @LIBXINERAMA@ +LIBZ = @LIBZ@ +LIB_KAB = @LIB_KAB@ +LIB_KDECORE = @LIB_KDECORE@ +LIB_KDEUI = @LIB_KDEUI@ +LIB_KFILE = @LIB_KFILE@ +LIB_KFM = @LIB_KFM@ +LIB_KFORMULA = @LIB_KFORMULA@ +LIB_KHTML = @LIB_KHTML@ +LIB_KIMGIO = @LIB_KIMGIO@ +LIB_KIO = @LIB_KIO@ +LIB_KPARTS = @LIB_KPARTS@ +LIB_KSPELL = @LIB_KSPELL@ +LIB_KSYCOCA = @LIB_KSYCOCA@ +LIB_KWRITE = @LIB_KWRITE@ +LIB_QT = @LIB_QT@ +LIB_SMB = @LIB_SMB@ +LIB_X11 = @LIB_X11@ +LN_S = @LN_S@ +MCOPIDL = @MCOPIDL@ +MEINPROC = @MEINPROC@ +MICO_INCLUDES = @MICO_INCLUDES@ +MICO_LDFLAGS = @MICO_LDFLAGS@ +MOC = @MOC@ +MSGFMT = @MSGFMT@ +NOOPT_CXXFLAGS = @NOOPT_CXXFLAGS@ +NOREPO = @NOREPO@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PAMLIBS = @PAMLIBS@ +PASSWDLIBS = @PASSWDLIBS@ +PYTHONINC = @PYTHONINC@ +PYTHONLIB = @PYTHONLIB@ +PYTHONMODDIR = @PYTHONMODDIR@ +QT_INCLUDES = @QT_INCLUDES@ +QT_LDFLAGS = @QT_LDFLAGS@ +RANLIB = @RANLIB@ +REPO = @REPO@ +SETUIDFLAGS = @SETUIDFLAGS@ +STRIP = @STRIP@ +TOPSUBDIRS = @TOPSUBDIRS@ +UIC = @UIC@ +UIC_TR = @UIC_TR@ +USER_INCLUDES = @USER_INCLUDES@ +USER_LDFLAGS = @USER_LDFLAGS@ +USE_EXCEPTIONS = @USE_EXCEPTIONS@ +USE_RTTI = @USE_RTTI@ +USE_THREADS = @USE_THREADS@ +VERSION = @VERSION@ +XGETTEXT = @XGETTEXT@ +XPMINC = @XPMINC@ +XPMLIB = @XPMLIB@ +X_EXTRA_LIBS = @X_EXTRA_LIBS@ +X_INCLUDES = @X_INCLUDES@ +X_LDFLAGS = @X_LDFLAGS@ +X_PRE_LIBS = @X_PRE_LIBS@ +all_includes = @all_includes@ +all_libraries = @all_libraries@ +am__include = @am__include@ +am__quote = @am__quote@ +idldir = @idldir@ +install_sh = @install_sh@ +jni_includes = @jni_includes@ +kde_appsdir = @kde_appsdir@ +kde_bindir = @kde_bindir@ +kde_confdir = @kde_confdir@ +kde_datadir = @kde_datadir@ +kde_htmldir = @kde_htmldir@ +kde_icondir = @kde_icondir@ +kde_includes = @kde_includes@ +kde_libraries = @kde_libraries@ +kde_libs_htmldir = @kde_libs_htmldir@ +kde_libs_prefix = @kde_libs_prefix@ +kde_locale = @kde_locale@ +kde_mimedir = @kde_mimedir@ +kde_moduledir = @kde_moduledir@ +kde_qtver = @kde_qtver@ +kde_servicesdir = @kde_servicesdir@ +kde_servicetypesdir = @kde_servicetypesdir@ +kde_sounddir = @kde_sounddir@ +kde_templatesdir = @kde_templatesdir@ +kde_wallpaperdir = @kde_wallpaperdir@ +micodir = @micodir@ +qt_includes = @qt_includes@ +qt_libraries = @qt_libraries@ +x_includes = @x_includes@ +x_libraries = @x_libraries@ + +EXTRA_DIST = $(wildcard *.html) $(wildcard *.c) $(wildcard *.h) $(wildcard *.asm) $(wildcard *.txt) \ + 8087_sav.asm HEADER.html c_lines.awk except.doc file_id.diz make.ini match.doc myio.cpp \ + myio.mak myiodemo.cpp myline.cpp mystream.cpp pdn.lst read.me resource.lst rg_qsort.c1 \ + rg_qsort.c2 snippets._c_ snippets.ndx snippets.txt snippets.wc storage.typ str.cpp str.doc + + +docs_DATA = $(EXTRA_DIST) + +docsdir = $(kde_htmldir)/en/kdevelop/$(subdir) +subdir = reference/C/CONTRIB/SNIP +mkinstalldirs = $(SHELL) $(top_srcdir)/admin/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +DIST_SOURCES = +DATA = $(docs_DATA) + +DIST_COMMON = Makefile.am Makefile.in +#>- all: all-am +#>+ 1 +all: docs-am all-am + +.SUFFIXES: + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) +#>- cd $(top_srcdir) && \ +#>- $(AUTOMAKE) --gnu reference/C/CONTRIB/SNIP/Makefile +#>+ 3 + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu reference/C/CONTRIB/SNIP/Makefile + cd $(top_srcdir) && perl admin/am_edit reference/C/CONTRIB/SNIP/Makefile.in +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) && \ + CONFIG_HEADERS= CONFIG_LINKS= \ + CONFIG_FILES=$(subdir)/$@ $(SHELL) ./config.status +uninstall-info-am: +install-docsDATA: $(docs_DATA) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(docsdir) + @list='$(docs_DATA)'; for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + f="`echo $$p | sed -e 's|^.*/||'`"; \ + echo " $(INSTALL_DATA) $$d$$p $(DESTDIR)$(docsdir)/$$f"; \ + $(INSTALL_DATA) $$d$$p $(DESTDIR)$(docsdir)/$$f; \ + done + +uninstall-docsDATA: + @$(NORMAL_UNINSTALL) + @list='$(docs_DATA)'; for p in $$list; do \ + f="`echo $$p | sed -e 's|^.*/||'`"; \ + echo " rm -f $(DESTDIR)$(docsdir)/$$f"; \ + rm -f $(DESTDIR)$(docsdir)/$$f; \ + done +tags: TAGS +TAGS: + + +#>- DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +#>+ 4 +KDE_DIST=memrev.c crc-16.c cursor.c spin.c absdisk.asm doansi_1.c do.c isramdsk.c mouse.c trim.c fmemops.c myline.h wordwrap.c cbtrap.asm mouse.h shel2dos.c tail.c prtoggle.c daynum.c ll_msort.c psplit.c video.c ansiflen.c amalloc.c fndislot.c redir.c big_mall.h eval.c scrnsave.c msb2ieee.c ansiself.c scanfrac.c truename.c tabtrick.c mkdirs.c where.c rm_all.c xtest.c isfopen.c jdn.c posixdir.c morse.c fsm.c rand1.c stats.c bitcnt_2.c getopts.c cal.c x00api.c getopts.h ferrorf.c maze_1.c clock.c x00api.h bitfiles.c vfname.c playlib.c strrepl.c treedir.c isnetdr.c enums.txt lbitops.c errfix.c factor.c hexdump.c cubic.c permute1.c ansiload.c ispow2.c getkey.c pr.c lsd.c scrnpick.c rfind1st.c stripeof.c doansi_2.c flnorm.c getcmt.c mem.c ansisys.c mem.h myio.h speed.c rmlead.c strrev.c rtlftrul.txt log.c calsupp.c dossort.c wb_fcopy.c fcompare.c bitops.c doscopy.c chgext.c fcopy.c setenvar.c bordcolr.c checkexe.c moon_age.c ifactor.c strucfil.c trapflag.asm sstrcpy.c posix_ls.c which_c.txt lsary.c unix2dos.c testcmt.c cast.h split.c flopcopy.c compiler.c doansi.h cctrap.asm prtscrn.c nonmsdos.txt killff.c ord_text.c stptok.c strdup.c chmod.c fpswitch.c jgrep.c rand2.c windchil.c msc_peek.c maze_2.c isxkbrd.c hexorint.c trapdemo.c playdemo.c ll_qsort.c tp6tod.c query.c bigfac.c commafmt.c cant.c mdalloc.c glbl_env.c permute2.c dirmask.c pbmsrch.c bastrngs.c rg_isort.c pluraltx.c break.c str27seg.c scaldate.c kbflip.c scaldate.h eng.c uuencode.c isshare.c lv1ws.c bmhisrch.c biport.c filcount.c drivsrch.c changprn.c biport.h roman.c bmhsrch.c combin.c mcb_env.c ctrlprnt.c pi.c pi.h sunriset.c toascii.c approx.c fscanbin.c rdxcnvrt.c ccomcall.c portable.h fln_fix.c os_id.c ext_keys.c getvol.c isqrt.c bitarray.c os_id.h ext_keys.h evsavres.txt w_wrap.c dosfuncs.txt w_wrap.h a2e.c environ.txt setimeto.c bascnvrt.c maze_3.c keywatch.c scroll.c tasker.c hires.asm ldfloor.c tasker.h patmat.c droptime.c match.c format.c checksum.c srchfile.c round.h missing.txt match.h crc-16f.c hstr_i.c ftime.c strupr.c head.c ftime.h style.c assignpr.c strftime.c cursize.c weird.c toolkit.h fsize.c kb_data.c hilobyte.h bincomp.c todaybak.c ptr_help.txt keylocks.c ltostr.c hugesort.c dspdtst.c isisbn.c ndpcheck.asm rg_ssort.c ansiscrn.h perm_idx.c cmdline.c absdiskc.c setvol.c getdcwd.c ltoa.c dblround.c files.c vt100.txt favail.c cpucheck.asm factoryl.c remtab.c joystick.c pfopen.c uudecode.c iostutor.txt mainmain.c pcnvrt.c addhndls.c vidport.c uclock.c dbl2long.c xstrcmp.c c_prec.txt crc_32.c str.h grep.c uclock.h hugeread.c faskbhit.c commconv.c timegetc.c prtstat.c getopt3.c translat.c fraction.c cerrinst.asm rmallws.c strsort.c bitstrng.c touch.c inchcvrt.c chbytes.c xfile.c memavail.c c_cmnt.c mterm.c coldboot.asm xfile.h getseg.c howdy.c center.c pmerge.c initvars.c pushdir.c isshift.c mystream.h bmhasrch.c mv.c stub.c scrnmacs.h strecpy.asm bresnham.c strat.c addpath.c strat.h vio.h lzhuf.c grafline.c editgets.c getstrng.c mktone.c iswprot.c cerrtrap.asm atr2ansi.c noreset.c vio.asm palndrom.c ansisys.txt sound.c prnspool.c rg_rand.c sound.h c_port.txt dspclock.c prnspool.h mem.txt sharing.txt whicharc.c crypt.c xstrcat.c reboot.c dd_struc.h 2dlife.c bitcnt_1.c tasker.txt fmtmoney.c rmtrail.c dos5boot.h wc.c cdir.c noctrlc.c iscons.c dirent.h drvs.c printq.c soundex.c bstr_i.c drvalid.c int2e.asm rndmize.c + +DISTFILES= $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) $(KDE_DIST) + + +top_distdir = ../../../.. +distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + if test -f $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + $(mkinstalldirs) "$(distdir)/$$dir"; \ + fi; \ + if test -d $$d/$$file; then \ + cp -pR $$d/$$file $(distdir) \ + || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(DATA) + +installdirs: + $(mkinstalldirs) $(DESTDIR)$(docsdir) + +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) stamp-h stamp-h[0-9]* + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +#>- clean: clean-am +#>+ 1 +clean: kde-rpo-clean clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + +distclean-am: clean-am distclean-generic distclean-libtool + +dvi: dvi-am + +dvi-am: + +info: info-am + +info-am: + +install-data-am: install-docsDATA + +install-exec-am: + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +uninstall-am: uninstall-docsDATA uninstall-info-am + +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + distclean distclean-generic distclean-libtool distdir dvi \ + dvi-am info info-am install install-am install-data \ + install-data-am install-docsDATA install-exec install-exec-am \ + install-info install-info-am install-man install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool uninstall uninstall-am uninstall-docsDATA \ + uninstall-info-am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: + +#>+ 2 +docs-am: + +#>+ 6 +force-reedit: + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu reference/C/CONTRIB/SNIP/Makefile + cd $(top_srcdir) && perl admin/am_edit reference/C/CONTRIB/SNIP/Makefile.in + + +#>+ 2 +final: + $(MAKE) all-am +#>+ 2 +final-install: + $(MAKE) install-am +#>+ 2 +no-final: + $(MAKE) all-am +#>+ 2 +no-final-install: + $(MAKE) install-am +#>+ 3 +cvs-clean: + $(MAKE) -f $(top_srcdir)/admin/Makefile.common cvs-clean + +#>+ 3 +kde-rpo-clean: + -rm -f *.rpo diff --git a/reference/C/CONTRIB/SNIP/a2e.c b/reference/C/CONTRIB/SNIP/a2e.c new file mode 100755 index 0000000..1185cba --- /dev/null +++ b/reference/C/CONTRIB/SNIP/a2e.c @@ -0,0 +1,51 @@ +/* +** ASCII <=> EBCDIC conversion functions +*/ + +static unsigned char a2e[256] = { + 0, 1, 2, 3, 55, 45, 46, 47, 22, 5, 37, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 60, 61, 50, 38, 24, 25, 63, 39, 28, 29, 30, 31, + 64, 79,127,123, 91,108, 80,125, 77, 93, 92, 78,107, 96, 75, 97, + 240,241,242,243,244,245,246,247,248,249,122, 94, 76,126,110,111, + 124,193,194,195,196,197,198,199,200,201,209,210,211,212,213,214, + 215,216,217,226,227,228,229,230,231,232,233, 74,224, 90, 95,109, + 121,129,130,131,132,133,134,135,136,137,145,146,147,148,149,150, + 151,152,153,162,163,164,165,166,167,168,169,192,106,208,161, 7, + 32, 33, 34, 35, 36, 21, 6, 23, 40, 41, 42, 43, 44, 9, 10, 27, + 48, 49, 26, 51, 52, 53, 54, 8, 56, 57, 58, 59, 4, 20, 62,225, + 65, 66, 67, 68, 69, 70, 71, 72, 73, 81, 82, 83, 84, 85, 86, 87, + 88, 89, 98, 99,100,101,102,103,104,105,112,113,114,115,116,117, + 118,119,120,128,138,139,140,141,142,143,144,154,155,156,157,158, + 159,160,170,171,172,173,174,175,176,177,178,179,180,181,182,183, + 184,185,186,187,188,189,190,191,202,203,204,205,206,207,218,219, + 220,221,222,223,234,235,236,237,238,239,250,251,252,253,254,255 +}; + +static unsigned char e2a[256] = { + 0, 1, 2, 3,156, 9,134,127,151,141,142, 11, 12, 13, 14, 15, + 16, 17, 18, 19,157,133, 8,135, 24, 25,146,143, 28, 29, 30, 31, + 128,129,130,131,132, 10, 23, 27,136,137,138,139,140, 5, 6, 7, + 144,145, 22,147,148,149,150, 4,152,153,154,155, 20, 21,158, 26, + 32,160,161,162,163,164,165,166,167,168, 91, 46, 60, 40, 43, 33, + 38,169,170,171,172,173,174,175,176,177, 93, 36, 42, 41, 59, 94, + 45, 47,178,179,180,181,182,183,184,185,124, 44, 37, 95, 62, 63, + 186,187,188,189,190,191,192,193,194, 96, 58, 35, 64, 39, 61, 34, + 195, 97, 98, 99,100,101,102,103,104,105,196,197,198,199,200,201, + 202,106,107,108,109,110,111,112,113,114,203,204,205,206,207,208, + 209,126,115,116,117,118,119,120,121,122,210,211,212,213,214,215, + 216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231, + 123, 65, 66, 67, 68, 69, 70, 71, 72, 73,232,233,234,235,236,237, + 125, 74, 75, 76, 77, 78, 79, 80, 81, 82,238,239,240,241,242,243, + 92,159, 83, 84, 85, 86, 87, 88, 89, 90,244,245,246,247,248,249, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,250,251,252,253,254,255 +}; + +char ASCIItoEBCDIC(const unsigned char c) +{ + return a2e[c]; +} + +char EBCDICtoASCII(const unsigned char c) +{ + return e2a[c]; +} diff --git a/reference/C/CONTRIB/SNIP/absdisk.asm b/reference/C/CONTRIB/SNIP/absdisk.asm new file mode 100755 index 0000000..43a87ea --- /dev/null +++ b/reference/C/CONTRIB/SNIP/absdisk.asm @@ -0,0 +1,72 @@ + page 55, 132 + +; +; ABSDISK.ASM +; +; Originally published as part of The MicroFirm Function Library +; This version released to the public domain by the author, Bob Stout +; +; Requires MASM 5.1 or later or equivalent +; +; Assemble with: MASM /Mx /z ... +; TASM /jMASM /mx /z ... +; + +% .MODEL memodel,C ;Add model support via + ;command line macro, + ;e.g. MASM /Dmemodel=LARGE ... + extrn _osmajor:BYTE + public absdisk + + .DATA +start dw ? +fill dw 0 +number dw ? +buf dw ?,? + + .CODE +absdisk PROC USES SI DI BP, func:BYTE, drive:WORD, num_sec:WORD, start_sec:WORD, buffer:PTR + mov AX,drive ;Get drive number in AL + mov AH,_osmajor ;Load OS version in AH + mov CX,num_sec ;Set up regs for DOS 3 call + mov DX,start_sec + IF @DataSize + push DS ;Save DS in L & C models + lds BX,buffer + ELSE + mov BX,buffer + ENDIF + cmp AH,4 ;DOS 4+? + jb doint ;No, skip it + mov start,DX ;Yes, fill in DCB structure + mov number,CX + mov buf,BX + mov buf+2,DS + mov cx,-1 + IF @DataSize ;Point to DCB + mov BX,@Data + mov DS,BX + ENDIF + mov bx,OFFSET start +doint: mov AH,func ;Read or Write? + cmp AH,25h + jne skip_1 + int 25h ;Read sector + jmp skip_3 +skip_1: cmp AH,26h + jne skip_2 + int 26h ;Write sector + jmp skip_3 +skip_2: stc ;Invalid command + mov AX,-1 +skip_3: jc bye ;Error? + mov AX,0 ;No, return SUCCESS +bye: add SP,2 ;Int 25h leave the flags on the stack + IF @DataSize + pop DS ;Restore DS in L & C models + ENDIF + ret + +absdisk ENDP + + end diff --git a/reference/C/CONTRIB/SNIP/absdiskc.c b/reference/C/CONTRIB/SNIP/absdiskc.c new file mode 100755 index 0000000..093724d --- /dev/null +++ b/reference/C/CONTRIB/SNIP/absdiskc.c @@ -0,0 +1,34 @@ +/* +** ABSDISKC.C - Functions to read and write absolute disk sectors +** (these will work with all versions of DOS 2-5). +** +** Public domain code by Bob Stout +** +** NOTE: These functions work by calling absdisk() from SNIPPETS file, +** ABSDISK.ASM. +*/ + +#include +#include + +int _cdecl absdisk(unsigned char function, + unsigned short drive, + size_t number_of_sectors, + size_t starting_sector, + void * sector_buffer); + +int AbsDiskRead(unsigned short drive, + size_t num_of_sectors, + size_t sector, + void *ptr) +{ + return absdisk(0x25, drive, num_of_sectors, (unsigned)sector, ptr); +} + +int AbsDiskWrite(unsigned short drive, + size_t num_of_sectors, + size_t sector, + void *ptr) +{ + return absdisk(0x26, drive, num_of_sectors, (unsigned)sector, ptr); +} diff --git a/reference/C/CONTRIB/SNIP/addhndls.c b/reference/C/CONTRIB/SNIP/addhndls.c new file mode 100755 index 0000000..892e550 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/addhndls.c @@ -0,0 +1,104 @@ +/* +** ADDHNDLS.C +** +** A compilation of public domain sources originally written by +** Doug Burger and Bob Jarvis +** +** Collected and modified for Zortech, Microsoft, and Borland by Bob Stout +** +** Demonstrates relocating the file handle table under DOS 3.x +** for having more than the usual 20 files open in a single +** program +*/ + +#include +#include +#include +#include + +#define TABLE_SIZE 255 /* NOTE: *Must* be <= FILES in CONFIG.SYS */ + +#ifdef TEST + #if !defined(__ZTC__) && !defined(__TURBOC__) /* i.e. #if MSC/QC */ + #include + #define MK_FP(seg,offset) \ + ((void far *)(((unsigned long)(seg)<<16) | (unsigned)(offset))) + + /* MSC's open() is funny - this code only works with _dos_open() */ + + int open(const char *name, int mode, ...) + { + int hdl; + + if (0 == _dos_open(name, mode, &hdl)) + return hdl; + else return -1; + } + #endif /* MSC */ +#endif /* TEST */ + +unsigned char handle_table[TABLE_SIZE]; /* table of file DOS handles */ +unsigned char far * far * handle_ptr; /* ptr to DOS's ptr to hand. */ +unsigned int far *handle_count; /* ptr to handle count */ + +int relocate(void) +{ + switch (_osmajor) + { + case 2: + return -1; + case 3: + if (3 > _osminor) + { /* by Doug Burger */ + unsigned int i; + + handle_count = MK_FP(_psp, 0x32); /* handle count at PSP:32h */ + handle_ptr = MK_FP(_psp, 0x34); /* table ptr at PSP:34h */ + for (i = 0; i < *handle_count; i++) /* relocate exiting table */ + handle_table[i] = (*handle_ptr)[i]; + for (i = *handle_count; i < TABLE_SIZE; i++) /* init. rest */ + handle_table[i] = 255; + *handle_ptr = handle_table; /* set pointer to new table */ + *handle_count = TABLE_SIZE; /* set new table size */ + return 0; + } + else + default: /* DOS 4+ */ + { /* by Bob Jarvis */ + union REGS regs; + + regs.h.ah = 0x67; + regs.x.bx = TABLE_SIZE | 1; /* has to be an odd number */ + + intdos(®s, ®s); + + if(regs.x.cflag) /* error */ + return -1; + else + return 0; + } + } +} /* relocate() */ + +/* +** Test code +*/ + +#ifdef TEST + +void main(void) +{ + int c, h; + + relocate(); + + c = 0; + while ((h = open("CON", O_RDONLY)) >= 0) /* DOS closes files */ + { + c++; /* on exit, so I */ + printf("handle = %d\n", h); /* don't bother */ + } /* saving handles */ + printf("total opened files = %d\n", c); +} /* ADDHNDLS.C */ + +#endif /* TEST */ diff --git a/reference/C/CONTRIB/SNIP/addpath.c b/reference/C/CONTRIB/SNIP/addpath.c new file mode 100755 index 0000000..9d41996 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/addpath.c @@ -0,0 +1,101 @@ +/* +** Append a new directory to the AUTOEXEC.BAT path +** +** public domain by Bob Stout +** also uses TRIM.C from SNIPPETS +*/ + +#include +#include + +char *trim(char *); + +#define TAG_1 "set path=" +#define TAG_2 "path=" + +typedef enum {ERROR = -1, SUCCESS} LOGICAL; + +#define NUL '\0' +#define LAST_CHAR(s) (((char *)s)[strlen(s) - 1]) + +#ifdef TESTDIR + #define ROOT "" /* While testing, do things in the current dir */ +#else + #define ROOT "\\" /* Otherwise, look for AUTOEXEC.BAT in the root */ +#endif + +LOGICAL addpath(char *newdir) +{ + FILE *autoexec, *tmp; + char fname[FILENAME_MAX], bakname[FILENAME_MAX]; + char tfname[L_tmpnam], tbakname[L_tmpnam]; + char *ptr; + + strcat(strcpy(fname, ROOT), "autoexec.bat"); + tmpnam(tfname); + tmpnam(tbakname); + + strcpy(bakname, fname); + if (NULL != (ptr = strrchr(bakname, '.'))) + { + if (NULL == strchr(ptr, '\\') && NULL == strchr(ptr, '/')) + *ptr = NUL; + } + strcat(bakname, ".bak"); + + rename(bakname, tbakname); + rename(fname, bakname); + + if (NULL == (autoexec = fopen(bakname, "r"))) + { + if (NULL == (autoexec = fopen(fname, "w"))) + return ERROR; + fprintf(autoexec, "SET PATH=%s\n", newdir); + fclose(autoexec); + remove(tbakname); + return SUCCESS; + } + if (NULL == (tmp = fopen(tfname, "w"))) + { + fclose(autoexec); + rename(bakname, fname); + rename(tbakname, bakname); + return ERROR; + } + else remove(tbakname); + + while (!feof(autoexec)) + { + char rline[256 + FILENAME_MAX]; + char tline[256 + FILENAME_MAX]; + + if (fgets(rline, 256, autoexec)) + { + trim(strcpy(tline, rline)); + if ((SUCCESS == strnicmp(tline, TAG_1, strlen(TAG_1))) || + (SUCCESS == strnicmp(tline, TAG_2, strlen(TAG_2)))) + { + if ('\n' == LAST_CHAR(rline)) + LAST_CHAR(rline) = NUL; + strcat(rline, (';' == LAST_CHAR(rline) ? "" : ";")); + strcat(strcat(rline, newdir), "\n"); + } + fputs(rline, tmp); + } + } + + fclose(autoexec); + fclose(tmp); + + rename(tfname, fname); + return SUCCESS; +} + +#ifdef TEST + +main() +{ + printf("addpath(mydir) returned %d\n", addpath("mydir")); +} + +#endif diff --git a/reference/C/CONTRIB/SNIP/amalloc.c b/reference/C/CONTRIB/SNIP/amalloc.c new file mode 100755 index 0000000..037ffa5 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/amalloc.c @@ -0,0 +1,124 @@ +/* + +AMALLOC - multi-dimensional malloc() + +Allocates a multidimensional array dynamically, at runtime, so that + 1: its elements can be accessed using multiple indirection + 2: it can be deallocated using a call to the standard free() function +Note: On PC's the max array size is 64K + +Paul Schlyter, 1992-02-09. Released to the public domain. + +*/ + + +#include +#include +#include + + +#define MAXDIMS 5 /* Defines the maximum number of dimensions */ +#define MAXSIZE ((size_t) -1L) /* Maximum size of array */ + + +void *amalloc( int esiz, void *initval, int dims, ... ) +/* + * Input: esiz size of each array elements, as given by sizeof + * initval pointer to initial value. NULL ==> zero fill + * dims number of dimensions: 1..MAXDIMS (5) + * ... number of elements in each dimension (int's) + * + * Returns: NULL error: out of memory, or illegal parameters + * otherwise base pointer to array + */ +{ + unsigned int dim[MAXDIMS], accdim[MAXDIMS]; + va_list ap; + int i, j; + long int totsiz; + void **q; + char *p, *r, *s; + + if (dims < 1 || dims > MAXDIMS) + return NULL; + + memset(dim, 0, sizeof(dim)); /* Read dimension numbers */ + memset(accdim, 0, sizeof(accdim)); + va_start(ap, dims); + dim[0] = accdim[0] = va_arg(ap,int); + for (i = 1; i < dims; i++) + { + dim[i] = va_arg(ap,int); + accdim[i] = accdim[i-1] * dim[i]; + } + va_end(ap); + + /* Compute total array size */ + totsiz = esiz * accdim[dims-1]; /* Data size */ + + for (i = 0; i < dims - 1; i++ ) /* Add space for pointers */ + totsiz += sizeof(void *) * accdim[i]; + + if (totsiz > MAXSIZE) /* Exit if totsiz too large */ + return NULL; + + p = malloc((size_t) totsiz); /* Allocate memory */ + if (p == NULL) /* Out-of-memory */ + return NULL; + memset(p, 0, (unsigned int) totsiz); /* Zero out allocated memory */ + q = (void **) p; + + if (dims == 1) + r = (char *) q + esiz * accdim[0]; + + for (i = 1; i < dims; i++) /* Fill in pointers */ + { + int siz; + int accd = accdim[i-1], d = dim[i]; + + siz = i == dims-1 ? esiz : sizeof(void *); + + r = (char *) q + sizeof(void *) * accd; + for (j = 0; j < accd; j++) + { + *q++ = r; + r += siz * d; + } + } + + if (initval != NULL) + { + for (s = (char *) q; s < r; s += esiz) + memcpy(s, initval, esiz); + } + + return p; + +} /* amalloc */ + + +#ifdef TEST /* Test program */ + +#include + +main() +{ + static char init_d[8] = { 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF }; + int init_i = 0x1111; + double *a = amalloc( sizeof(double), init_d, 1, 4 ); + double **b = amalloc( sizeof(double), init_d, 2, 4, 5 ); + double ***c = amalloc( sizeof(double), init_d, 3, 4, 5, 6 ); + int ***d = amalloc( sizeof(int), &init_i, 3, 4, 5, 6 ); + int i, j, k; + + for (i = 0; i < 4; i++) + for (j = 0; j < 5; j++ ) + for (k = 0; k < 6; k++ ) + d[i][j][k] = (i * 256) + (j * 16) + k; + + a = a, b = b, c = c; + + return 0; +} + +#endif diff --git a/reference/C/CONTRIB/SNIP/ansiflen.c b/reference/C/CONTRIB/SNIP/ansiflen.c new file mode 100755 index 0000000..4dec5cd --- /dev/null +++ b/reference/C/CONTRIB/SNIP/ansiflen.c @@ -0,0 +1,34 @@ +/* +** FLENGTH.C - a simple function using all ANSI-standard functions +** to determine the size of a file. +** +** Public domain by Bob Jarvis. +*/ + +#include + +long flength(char *fname) +{ + FILE *fptr; + long length = -1L; + + fptr = fopen(fname, "rb"); + if(fptr != NULL) + { + fseek(fptr, 0L, SEEK_END); + length = ftell(fptr); + fclose(fptr); + } + + return length; +} + +#ifdef TEST + +main(int argc, char *argv[]) +{ + printf("Length of %s = %ld\n", argv[0], flength(argv[0])); + return 0; +} + +#endif /* TEST */ diff --git a/reference/C/CONTRIB/SNIP/ansiload.c b/reference/C/CONTRIB/SNIP/ansiload.c new file mode 100755 index 0000000..e4dadc0 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/ansiload.c @@ -0,0 +1,66 @@ +/* +** ANSILOAD.C - tries to detect if an ANSI-style driver is loaded +** +** public domain by Bob Jarvis +*/ + +#include +#include + +typedef enum {FALSE, TRUE} LOGICAL; + +void goto_rc(int row, int col) +{ + union REGS regs; + + regs.h.ah = 2; + regs.h.bh = 0; /* assumes we're using video page 0 */ + regs.h.dh = (unsigned char)row; + regs.h.dl = (unsigned char)col; + + int86(0x10, ®s, ®s); +} + +void get_rc(int *row, int *col) +{ + union REGS regs; + + regs.h.ah = 3; + regs.h.bh = 0; /* again, assume video page 0 */ + + int86(0x10, ®s, ®s); + + *row = regs.h.dh; + *col = regs.h.dl; +} + +int is_ansi_loaded(void) +{ + int save_r, save_c; + int new_r, new_c; + int isloaded; + + get_rc(&save_r, &save_c); + goto_rc(15,15); + fputs("\x1B[0;0H", stderr); + + get_rc(&new_r, &new_c); + + if(new_r == 0 && new_c == 0) + isloaded = TRUE; + else + { + isloaded = FALSE; + fputs("\b\b\b\b\b\b \b\b\b\b\b\b", stderr); + } + + goto_rc(save_r, save_c); + return isloaded; +} + +void main(void) +{ + if(is_ansi_loaded()) + puts("ANSI.SYS is loaded"); + else puts("ANSI.SYS is NOT loaded"); +} diff --git a/reference/C/CONTRIB/SNIP/ansiscrn.h b/reference/C/CONTRIB/SNIP/ansiscrn.h new file mode 100755 index 0000000..9338b68 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/ansiscrn.h @@ -0,0 +1,72 @@ +#ifndef ANSISCRN +#define ANSISCRN +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * ANSISCRN.H + * + * #include implementation of ANSI screen control codes + * Contributed to the public domain 12-26-91 by + * Matthew J. Glass. + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#include + +#define ESC 27 +#define ANSI_cup(a,b) printf("%c[%d;%dH",ESC,a,b) +#define ANSI_up(a) printf("%c[%dA",ESC,a) +#define ANSI_down(a) printf("%c[%dB",ESC,a) +#define ANSI_right(a) printf("%c[%dC",ESC,a) +#define ANSI_left(a) printf("%c[%dD",ESC,a) +#define ANSI_locate(a,b) printf("%c[%d;%df",ESC,a,b) +#define ANSI_savecurs() printf("%c[S",ESC) +#define ANSI_restcurs() printf("%c[U",ESC) +#define ANSI_cls() printf("%c[2J",ESC) +#define ANSI_cleol() printf("%c[K",ESC) +#define ANSI_margins(a,b) printf("%c[%d;%dr",ESC,a,b) + +#define NORMAL 0 /* attributes for ANSI_attrib() */ +#define BOLD 1 +#define USCORE 2 +#define BLINK 3 +#define REVERSE 4 +#define INVIS 5 + +#define BLACK 0 /* colors for ANSI_bg_color() and */ +#define RED 1 /* ANSI_fg_color. */ +#define GREEN 2 +#define YELLOW 3 +#define BLUE 4 +#define MAGENTA 5 +#define CYAN 6 +#define WHITE 7 +#define B_BLACK 8 /* bright colors for ANSI_fg_color() */ +#define B_RED 9 +#define B_GREEN 10 +#define B_YELLOW 11 +#define B_BLUE 12 +#define B_MAGENTA 13 +#define B_CYAN 14 +#define B_WHITE 15 + +static char *_atrb_plt[] = { + "0","1","4","5","7","8" + }; + +static char *_fg_plt[] = { + "0;30","0;31","0;32","0;33", + "0;34","0;35","0;36","0;37", + "1;30","1;31","1;32","1;33", + "1;34","1;35","1;36","1;37" + }; + +static char *_bg_plt[] = { + "40","41","42","43", + "44","45","46","47" + }; + +#define ANSI_attrib(a) printf("%c[%sm",ESC,_atrb_plt[a]) +#define ANSI_fg_color(a) printf("%c[%sm",ESC, _fg_plt[a] ) +#define ANSI_bg_color(a) printf("%c[%sm",ESC, _bg_plt[a] ) + +#endif /* ANSISCRN */ diff --git a/reference/C/CONTRIB/SNIP/ansiself.c b/reference/C/CONTRIB/SNIP/ansiself.c new file mode 100755 index 0000000..863ee4e --- /dev/null +++ b/reference/C/CONTRIB/SNIP/ansiself.c @@ -0,0 +1,10 @@ +/* +** Challenge: Write the smallest self-duplicating program, not +** reading the source file, which successfully exits and is strictly +** conforming Standard C. +** +** Public domain response by Thad Smith +*/ + +#include +main(){char*c="\\\"#include%cmain(){char*c=%c%c%c%.102s%cn%c;printf(c+2,c[102],c[1],*c,*c,c,*c,c[1]);exit(0);}\n";printf(c+2,c[102],c[1],*c,*c,c,*c,c[1]);exit(0);} diff --git a/reference/C/CONTRIB/SNIP/ansisys.c b/reference/C/CONTRIB/SNIP/ansisys.c new file mode 100755 index 0000000..d90322f --- /dev/null +++ b/reference/C/CONTRIB/SNIP/ansisys.c @@ -0,0 +1,60 @@ +/***************************************************************************** + * + * program that detects the presence (or absence) of an ANSI device driver. + * + * Returns: + * + * errorlevel 0: Ansi devicedriver not detected. + * errorlevel 1: Ansi devicedriver detected. + * + ***************************************************************************** + */ + +#include +#include +#include + + + +/********************************** print () ********************************* + * + * A dum print string routine + * + ***************************************************************************** + */ + +void print(char *p) +{ + while(*p) + putchar(*p++); + fflush(stdout); /* necessary for ZTC */ + +} /* print () */ + +/********************************** main () ********************************** + * + * Detect whether ANSI.SYS is present and return 1 if so, else returns 0 + * + ***************************************************************************** + */ + +int main(void) +{ + char buffer [31]; /* temporary buffer */ + int nr=0; /* counter */ + + print("\x1b[6n\r \r"); /* ask for ansi device report */ + + while ((0 !=kbhit()) && (nr<30))/* read whatever input is present */ + buffer[nr++] = (char)getch(); + + buffer[nr]='\0'; /* zero terminate string */ + + if (strstr(buffer, "\x1b[")) /* check precense of device report */ + return 1; /* signal ANSI.SYS present */ + else return 0; /* signal ANSI.SYS not present */ + + +} /* main () */ + +/********************************** end *************************************/ diff --git a/reference/C/CONTRIB/SNIP/ansisys.txt b/reference/C/CONTRIB/SNIP/ansisys.txt new file mode 100755 index 0000000..4bf1541 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/ansisys.txt @@ -0,0 +1,226 @@ + + ANSI.SYS's Escape Sequences Files. + + + + WARNING: You must press the ESC key, the [, the number wanted, + then the tiny M key. + + Graphics functions: + + 0 : All Attributes Off + 1 : Bold On + 4 : Underscore (Monochrome Display Only) + 5 : Blink On + 7 : Reverse Video On + 8 : Concealed On + + That's all for the Graphics Functions existing in ANSI.SYS. + + Foreground colors: + + 30 : Black 34 : Blue + 31 : Red 35 : Magenta + 32 : Green 36 : Cyan + 33 : Yellow 37 : White + + Background colors: + + 40 : Black 44 : Blue + 41 : Red 45 : Magenta + 42 : Green 46 : Cyan + 43 : Yellow 47 : White + + ( Background is finally the Foreground + 10 ) + + -------------------- + + Code Description + ------------------------------------------------------------------------ + Pn : Numeric Parameter - a Decimal Number that you Specify with + ASCII digits. + + Ps : Selective Paramater - a Decimal Number that you use to + select a Subfunction. You may specify More than One Sub- + function by separating the parameters with semicolons. + + Pl : Line Parameter - a Decimal Number that you Specify with + ASCII digits. + + Pc : Column Paramater - a Decimal Number that you Specify with + ASCII digits. + + ------------------ + + Don't Forget! All theses sequences are precede by the ESC key. + + ------------------ + Sequence Function + ------------------------------------------------------------------------ + [Pl;Pc H : Cursor Position (CUP) + + [Pl;Pc F : Horizontal & Vertical Position (HVP). + CUP and HVP move the cursor to the position specified + by the parameters. When no parameters are provided, + the cursor move to the home position (the upper-left + corner of the screen). + + [Pn A : Cursor Up (CUU) + This sequence moves the cursor up Pn lines without chan- + ging columns. If the cursor is Already on the Top line, + then it's ignores the CUU sequence. + + [Pn B : Cursor Down (CUD) + This sequence moves the cursor down Pn lines without chan- + ging columns. If the cursor is already on the bottom line, + then it's igrnores the CUD sequence. + + [Pn C : Cursor Forward (CUF) + The CUF sequence moves the cursor forward Pn columns with- + out changing lines. If the cursor is already in the far + right column, then it's ignores the CUF sequence. + + [Pn D : Cursor Backward (CUB) + This escape sequence moves the cursor back Pn columns with- + out changing lines. If the cursor is already in the far + left columns, then it's ignore the CUB sequence. + + [6n : Device Status Report (DSR) + The console driver outputs an RCP sequence when it receives + + the DSR escape sequence. + + [s : Save Cursor Position (SCP) + The console driver saves the current cursor position. This + position can be restored with the RCP sequence. + + [u : Restore Cursor Position (RCP) + This sequence restores the cursor position to the value it + had when the console driver received the SCP sequence. + + [2j : Erase Display (ED) + The ED sequence erases the screen. The cursor then goes + to the home position. + + [K : Erase Line (EL) + This sequences erases from the cursor to the end of the + line (including cursor position). + + [Ps; ... ; Ps m: Set Graphics Rendition (SGR) + The SGR escape sequence calls the graphic functions + specified by the following numeric parameters. These + functions remain until the next occurence of an SGR + escape sequence. + + [=Ps h Set mode (SM) + [=h The SM escape sequence changes the screen width or type + [=0h to one of the following numeric parameters: + + Screen Width Parameters + ---------------------------------- + 0 : 40 x 25 B&W + 1 : 40 x 25 color + 2 : 80 x 25 B&W + 3 : 80 x 25 color + 4 : 320 x 200 color + 5 : 320 x 200 B&W + 6 : 640 x 200 B&W + 7 : Wraps at the end of Each line + 14 : 640 x 200 color + 15 : 640 x 350 mono + 16 : 640 x 350 color + 17 : 640 x 480 color + 18 : 640 x 480 color (both 17-18 are good) + 19 : 320 x 200 color + ------------------------------------ + + [= Ps 1 : Reset mode (RM) + Parameters for RM are the same as for SM (Set Mode) + except parameter 7 resets the mode that causes wrapping + at the end of each line. + + [code;string;...p: Allows redefinition of keyboard keys to a specified + string where: + 'string' is either the ASCII code for a single character + or a string contained in quotation marks. For example, + both 65 and "A" can be used to represent an uppercase. + 'code' is one or more of the following values that re- + present keyboard keys. Semicolons shown in this table + must be entered in addition to the required semicolons + in the command line. + + Key Code + ------------------------------------------------------------------------- + Alone Shift- Ctrl- Alt- + ------------------------------------------------------------------------- + F1 0;59 0;84 0;94 0;104 + F2 0;60 0;85 0;95 0;105 + F3 0;61 0;86 0;96 0;106 + F4 0;62 0;87 0;97 0;107 + F5 0;63 0;88 0;98 0;108 + F6 0;64 0;89 0;90 0;109 + F7 0;65 0;90 0;100 0;110 + F8 0;66 0;91 0;101 0;111 + F9 0;67 0;92 0;102 0;112 + F10 0;68 0;93 0;103 0;113 + F11 0;133 0;135 0;137 0;139 + F12 0;134 0;136 0;138 0;140 + Home 0;71 55 0;119 ----- + Up Arrow 0;72 56 ----- ----- + Page Up 0;73 57 0;132 ----- + Left Arrow 0;75 52 0;115 ----- + Down Arrow 0;77 54 0;116 ----- + End 0;79 49 0;117 ----- + Page Down 0;81 51 0;118 ----- + Insert 0;82 48 ----- ----- + Delete 0;83 46 ----- ----- + Printscreen ----- ----- 0;114 ----- + + ------------------------------------------ + and for the keyboard's alphabeticals keys: + ------------------------------------------ + + Key Code + ------------------------------------------------------------------------ + Alone Shift- Ctrl- Alt- + ------------------------------------------------------------------------ + A 97 65 1 0;30 + B 98 66 2 0;48 + C 99 67 3 0;46 + D 100 68 4 0;32 + E 101 69 5 0;18 + F 102 70 6 0;33 + G 103 71 7 0;34 + H 104 72 8 0;35 + I 105 73 9 0;23 + J 106 74 10 0;36 + K 107 75 11 0;37 + L 108 76 12 0;38 + M 109 77 13 0;50 + N 110 78 14 0;49 + O 111 79 15 0;24 + P 112 80 16 0;25 + Q 113 81 17 0;16 + R 114 82 18 0;19 + S 115 83 19 0;31 + T 116 84 20 0;20 + U 117 85 21 0;22 + V 118 86 22 0;47 + W 119 87 23 0;17 + X 120 88 24 0;45 + Y 121 89 25 0;21 + Z 122 90 26 0;44 + 1 49 33 ----- 0;120 + 2 50 64 ----- 0;121 + 3 51 35 ----- 0;122 + 4 52 36 ----- 0;123 + 5 53 37 ----- 0;124 + 6 54 94 ----- 0;126 + 7 55 38 ----- 0;127 + 8 56 42 ----- 0;128 + 9 57 40 ----- 0;129 + 0 48 41 ----- 0;130 + . 45 95 ----- 0;131 + = 61 43 ----- ----- + TAB 9 0;15 ----- ----- + NULL 0;3 ----- ----- ----- diff --git a/reference/C/CONTRIB/SNIP/approx.c b/reference/C/CONTRIB/SNIP/approx.c new file mode 100755 index 0000000..319525c --- /dev/null +++ b/reference/C/CONTRIB/SNIP/approx.c @@ -0,0 +1,168 @@ +/*************************************************************** + * + * Fuzzy string searching subroutines + * + * Author: John Rex + * Date: August, 1988 + * References: (1) Computer Algorithms, by Sara Baase + * Addison-Wesley, 1988, pp 242-4. + * (2) Hall PAV, Dowling GR: "Approximate string matching", + * ACM Computing Surveys, 12:381-402, 1980. + * + * Verified on: + * Datalite, DeSmet, Ecosoft, Lattice, MetaWare, MSC, Turbo, Watcom + * + * Compile time preprocessor switches: + * DEBUG - if defined, include test driver + * + * Usage: + * + * char *pattern, *text; - search for pattern in text + * int degree; - degree of allowed mismatch + * char *start, *end; + * int howclose; + * + * void App_init(pattern, text, degree); - setup routine + * void App_next(&start, &end, &howclose); - find next match + * + * - searching is done when App_next() returns start==NULL + * + **************************************************************/ + +#define DEBUG 1 + +#include +#include +#include + +/* local, static data */ + +static char *Text, *Pattern; /* pointers to search strings */ +static int Textloc; /* current search position in Text */ +static int Plen; /* length of Pattern */ +static int Degree; /* max degree of allowed mismatch */ +static int *Ldiff, *Rdiff; /* dynamic difference arrays */ +static int *Loff, *Roff; /* used to calculate start of match */ + +void App_init(char *pattern, char *text, int degree) +{ + int i; + + /* save parameters */ + + Text = text; + Pattern = pattern; + Degree = degree; + + /* initialize */ + + Plen = strlen(pattern); + Ldiff = (int *) malloc(sizeof(int) * (Plen + 1) * 4); + Rdiff = Ldiff + Plen + 1; + Loff = Rdiff + Plen + 1; + Roff = Loff + Plen + 1; + for (i = 0; i <= Plen; i++) + { + Rdiff[i] = i; /* initial values for right-hand column */ + Roff[i] = 1; + } + + Textloc = -1; /* current offset into Text */ +} + +void App_next(char **start, char **end, int *howclose) +{ + int *temp, a, b, c, i; + + *start = NULL; + while (*start == NULL) /* start computing columns */ + { + if (Text[++Textloc] == '\0') /* out of text to search! */ + break; + + temp = Rdiff; /* move right-hand column to left ... */ + Rdiff = Ldiff; /* ... so that we can compute new ... */ + Ldiff = temp; /* ... right-hand column */ + Rdiff[0] = 0; /* top (boundary) row */ + + temp = Roff; /* and swap offset arrays, too */ + Roff = Loff; + Loff = temp; + Roff[1] = 0; + + for (i = 0; i < Plen; i++) /* run through pattern */ + { + /* compute a, b, & c as the three adjacent cells ... */ + + if (Pattern[i] == Text[Textloc]) + a = Ldiff[i]; + else a = Ldiff[i] + 1; + b = Ldiff[i+1] + 1; + c = Rdiff[i] + 1; + + /* ... now pick minimum ... */ + + if (b < a) + a = b; + if (c < a) + a = c; + + /* ... and store */ + + Rdiff[i+1] = a; + } + + /* now update offset array */ + /* the values in the offset arrays are added to the + current location to determine the beginning of the + mismatched substring. (see text for details) */ + + if (Plen > 1) for (i=2; i<=Plen; i++) + { + if (Ldiff[i-1] < Rdiff[i]) + Roff[i] = Loff[i-1] - 1; + else if (Rdiff[i-1] < Rdiff[i]) + Roff[i] = Roff[i-1]; + else if (Ldiff[i] < Rdiff[i]) + Roff[i] = Loff[i] - 1; + else /* Ldiff[i-1] == Rdiff[i] */ + Roff[i] = Loff[i-1] - 1; + } + + /* now, do we have an approximate match? */ + + if (Rdiff[Plen] <= Degree) /* indeed so! */ + { + *end = Text + Textloc; + *start = *end + Roff[Plen]; + *howclose = Rdiff[Plen]; + } + } + + if (start == NULL) /* all done - free dynamic arrays */ + free(Ldiff); +} + +#ifdef DEBUG + +void main(int argc, char **argv) +{ + char *begin, *end; + int howclose; + + if (argc != 4) + { + puts("Usage is: approx pattern text degree\n"); + exit(0); + } + + App_init(argv[1], argv[2], atoi(argv[3])); + App_next(&begin, &end, &howclose); + while (begin != NULL) + { + printf("Degree %d: %.*s\n", howclose, end-begin+1, begin); + App_next(&begin, &end, &howclose); + } +} + +#endif diff --git a/reference/C/CONTRIB/SNIP/assignpr.c b/reference/C/CONTRIB/SNIP/assignpr.c new file mode 100755 index 0000000..45fac83 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/assignpr.c @@ -0,0 +1,56 @@ +/* +** ASSIGNPR.C +** +** Multiple printer support with default to a single printer +** connected to the PRN device. +** +** Original Copyright 1988-1991 by Bob Stout as part of +** the MicroFirm Function Library (MFL) +** +** This subset version is functionally identical to the +** version originally published by the author in Tech Specialist +** magazine and is hereby donated to the public domain. +*/ + +#include + +#define NUM_OF_PRNTRS 6 + +FILE *printer[NUM_OF_PRNTRS] = {stdprn}; + +/* +** assign_printer() +** +** Call with printer number and device name +** +** printer number should be in the range of 0 to NUM_OF_PRNTRS-1 +** device should be "LPT1", "LPT2", "LPT3", "COM1", COM2", or a log file +** +** Returns 0 if successful, -1 if error +** +** Then do all printer output with fprintf(), fputs(), fputc(), etc. +** using printer[printer_number] as the output stream +*/ + +int cdecl assign_printer(int number, char *device) +{ + FILE *fp; + + if (NUM_OF_PRNTRS <= number || NULL == (fp = fopen(device, "w"))) + return -1; + printer[number] = fp; + return 0; +} + +#ifdef TEST /* Test code follows */ + +main() +{ /* Leave printer[0] = stdprn */ + assign_printer(1, "CON"); /* Set printer[1] to the screen */ + assign_printer(2, "p.log"); /* Set printer[2] to log file */ + fputs("This is a printer test\n", printer[0]); + fputs("This is a screen test\n", printer[1]); + fputs("This is a log test\n", printer[2]); +} + +#endif /* TEST */ diff --git a/reference/C/CONTRIB/SNIP/atr2ansi.c b/reference/C/CONTRIB/SNIP/atr2ansi.c new file mode 100755 index 0000000..dc763fb --- /dev/null +++ b/reference/C/CONTRIB/SNIP/atr2ansi.c @@ -0,0 +1,80 @@ +/* +** Form a command string for ANSI.SYS to set a given video attribute +** +** Public domain demo by Bob Stout +*/ + +/* video attributes */ + +#define BLINKING 0x87 +#define REVERSE 0x70 +#define REVBLINK 0xf0 +#define NORMAL 0x07 +#define HIGHLITE 0x0f +#define HIGHBLINK 0x8f +#define BLINKBIT 0x80 /* OR in to cause blink */ +#define HILTBIT 0x08 /* OR in to cause highlight */ + +/* +** colors -- Use as is for foreground colors +** For background, shift left by 4 and OR with +** foreground and possible video attributes +*/ + +#define BLACK 0 +#define BLUE 1 +#define GREEN 2 +#define CYAN 3 +#define RED 4 +#define MAGENTA 5 +#define BROWN 6 +#define WHITE 7 +#define GRAY 8 +#define LTBLUE 9 +#define LTGREEN 10 +#define LTCYAN 11 +#define LTRED 12 +#define LTMAGENTA 13 +#define YELLOW 14 +#define HIWHITE 15 /* hi-intensity white */ + +#define BG_(a) (((a) & 0x7f) << 4) + +/* +** Example: +** Video attribute of yellow text on blue background = BG_(BLUE)+YELLOW +*/ + +char *make_ansi(int vatr) +{ + void add_str(char *, char *); + static char string[40]; + + static char *fore[8] = {"30","34","32","36","31","35","33","37"}; + static char *back[8] = {"40","44","42","46","41","45","43","47"}; + + strcpy(string, "\033["); + if (vatr == 0x07) + strcat(string, "0"); + else + { + if (vatr & 0x80) + add_str(string, "5"); + if (vatr & 0x08) + add_str(string, "1"); + add_str(string, fore[vatr & 0x07]); + add_str(string, back[(vatr & 0x70) >> 4]); + } + strcat(string, "m"); + return string; +} + +void add_str(char *string1, char *string2) +{ + char last_char; + + last_char = string1[strlen(string1) - 1]; + if (last_char != '[') + strcat(string1, ";"); + strcat(string1, string2); +} diff --git a/reference/C/CONTRIB/SNIP/bascnvrt.c b/reference/C/CONTRIB/SNIP/bascnvrt.c new file mode 100755 index 0000000..1d685ef --- /dev/null +++ b/reference/C/CONTRIB/SNIP/bascnvrt.c @@ -0,0 +1,49 @@ +/* +** BASCNVRT.C - Convert between number bases +** +** public domain demo by Bob Stout +*/ + +#include +#ifdef TEST + #include +#endif + +/* +** Calling parameters: 1 - Number string to be converted +** 2 - Buffer for the converted output +** 3 - Radix (base) of the input +** 4 - Radix of the output +** +** Returns: Pointer to converted output +*/ + +char *base_convert(const char *in, char *out, int rin, int rout) +{ + long n; + char *dummy; + + n = strtol(in, &dummy, rin); + return ltoa(n, out, rout); +} + +#ifdef TEST + +int main(int argc, char *argv[]) +{ + int rin, rout; + char buf[40]; + + if (4 > argc) + { + puts("Usage: BASCNVRT "); + return(-1); + } + rin = atoi(argv[2]); + rout = atoi(argv[3]); + printf("%s (base %d) = %s (base %d)\n", argv[1], rin, + base_convert((const char *)argv[1], buf, rin, rout), rout); + return 0; +} + +#endif diff --git a/reference/C/CONTRIB/SNIP/bastrngs.c b/reference/C/CONTRIB/SNIP/bastrngs.c new file mode 100755 index 0000000..54d87d2 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/bastrngs.c @@ -0,0 +1,144 @@ +/* +** BASIC-like string operations +** +** public domain by Bob Stout +*/ + +#include +#include +#include +#include +#include + +static int stralloc_ptr; +static char *strings[8]; +static int str_tag[8]; + +/* +** stralloc() is the key function in this package, maintaining a pool of +** reusable strings. +*/ + +char *stralloc(size_t length) +{ + register int i; + + i = stralloc_ptr++; + if ((!strings[i]) || (length > strlen(strings[i]))) + { + assert(strings[i] = (char *)realloc(strings[i], length)); + str_tag[i] = -1; + } + else str_tag[i] = 0; + stralloc_ptr &= 7; + return (strings[i]); + /* Maintains 8 strings in a circular buffer */ +} + +/* +** free the string pool. +*/ + +void str_free(char *string) +{ + register int i; + + for (i = 0; i < 8; ++i) + { + if (strings[i] == string) + { + if (str_tag[i]) + free(strings[i]); + return; + } + } +} + +/* +** return the leftmost N characters from a string +*/ + +char *left(char *string, size_t N) +{ + char *buf; + size_t strlength = strlen(string); + + if (N > strlength) + N = strlength; + buf = stralloc(N + 1); + memcpy(buf, string, N); + buf[N] = '\0'; + return buf; +} + +/* +** return the rightmost N characters from a string +*/ + +char *right(char *string, size_t N) +{ + char *buf; + size_t strlength = strlen(string); + + if (N > strlength) + N = strlength; + buf = stralloc(N + 1); + strcpy(buf, &string[strlength-N]); + return buf; +} + +/* +** return a substring, N characters long beginning at position M +*/ + +char *mid(char *string, size_t M, size_t N) +{ + char *buf; + size_t strlength = strlen(string); + + if (M > strlength) + return NULL; + if (N > (strlength - M)) + N = strlength - M; + buf = stralloc(N + 1); + memcpy(buf, &string[M-1], N); + buf[N] = '\0'; + return buf; +} + +/* +** string concatenation function, equivalent to A$=B$+C$+... +*/ + +char *string_add(char *string, ...) +{ + va_list arg_ptr; + char *temp1, *temp2, *buf; + + va_start(arg_ptr, string); + temp1 = string; + do + { + if(NULL == (temp2 = va_arg(arg_ptr, char *))) + break; + buf = stralloc(strlen(temp1) + strlen(temp2) + 1); + temp1 = strcat(strcpy(buf, temp1), temp2); + } while (NULL != temp2); + return temp1; +} + +#ifdef TEST + +/* +** Demo main() +*/ + +void main(void) +{ + char *x = "European", *y = "Hardware", *z = "Skaters"; + + z = string_add(left(x, 2), right(y, 2), mid(z, 2, 2), "!", NULL); + puts(z); +} + +#endif /* TEST */ diff --git a/reference/C/CONTRIB/SNIP/big_mall.h b/reference/C/CONTRIB/SNIP/big_mall.h new file mode 100755 index 0000000..bec4b3a --- /dev/null +++ b/reference/C/CONTRIB/SNIP/big_mall.h @@ -0,0 +1,15 @@ +/* +** void _far *BigMalloc(unsigned long num_elem, size_t size_elem) +*/ + +#ifdef MSDOS + #if defined(__TURBOC__) || defined(__ZTC__) + #ifdef __TURBOC__ + #define _far far + #endif + #define BigMalloc(i,n) (void _far *)farmalloc(i*n) + #else /* MSC, Watcom */ + #define BigMalloc(i,n) (void _far *)halloc(i,n) +#else + #define BigMalloc(i,n) malloc(i*n) +#endif diff --git a/reference/C/CONTRIB/SNIP/bigfac.c b/reference/C/CONTRIB/SNIP/bigfac.c new file mode 100755 index 0000000..5e51077 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/bigfac.c @@ -0,0 +1,122 @@ +/* +** bigfac.c -- put into the public domain by Carl Declerck +*/ + +#include +#include +#include + +#define BUFFLEN 8192 +#define BUFFER ((char *) malloc(BUFFLEN)) + +void main (void); +void multiply (char *, char *, char *); +void zero_buffer (char *); +void minus_one (char *); +int isnull (char *); +void factorial (char *); + +void main (void) +{ + char *g = BUFFER; + + printf ("Enter a number: "); + scanf ("%s", g); + printf ("Factorial of %s is: ", g); + factorial (g); + printf ("%s\n", g); + free (g); +} + +void multiply (char *g1, char *g2, char *g3) +{ + int gp1, gp2, cumpos, respos, mod, div; + int cmod, cdiv, resoff, wdig1, wdig2, base; + + zero_buffer (g3); + for (gp2 = strlen(g2) - 1; gp2 >= 0; gp2--) + { + wdig2 = *(g2 + gp2) - 48; + resoff = strlen(g2) - gp2 - 1; + respos = BUFFLEN - resoff - 2; + for (gp1 = strlen(g1) - 1; gp1 >= 0; gp1--) + { + wdig1 = *(g1 + gp1) - 48; + mod = (wdig1 * wdig2) % 10; + div = (wdig1 * wdig2) / 10; + base = *(g3 + respos) - 48; + cmod = (base + mod) % 10; + cdiv = (base + mod) / 10 + div; + *(g3 + respos) = (char)(cmod + 48); + cumpos = --respos; + while (cdiv > 0) + { + base = *(g3 + cumpos) - 48; + *(g3 + cumpos--) = (char)((base + cdiv) % 10 + 48); + cdiv = (base + cdiv) / 10; + } + } + } + for (respos = 0; *(g3 + respos) == '0'; respos++) + ; + strcpy (g3, (char *) (g3 + respos)); + if (*g3 == 0) + strcpy (g3, "0"); +} + +void zero_buffer (char *buff) +{ + int cnt; + + for (cnt= 0; cnt < BUFFLEN; cnt++) + *(buff + cnt) = '0'; + *(buff + BUFFLEN - 1) = 0; +} + +void minus_one (char *g) +{ + int p; + char digit; + + p = strlen(g) - 1; + digit = *(g + p); + while (digit == '0') + { + *(g + p--) = '9'; + digit = *(g + p); + } + *(g + p) -= 1; +} + +int isnull (char *g) +{ + int p, ok = 1; + + for (p = 0; p < (int)(strlen(g)); p++) + if (*(g + p) != '0') + ok = 0; + return (ok); +} + +void factorial (char *g) +{ + char *h1 = BUFFER, *h2 = BUFFER; + + strcpy (h1, "1"); + while (!isnull(g)) + { + multiply (h1, g, h2); + strcpy (h1, h2); + minus_one (g); + } + strcpy (g, h1); + free (h1); + free (h2); +} + +/* +** The principal function is multiply(), it 'multiplies' two +** character-strings of arbritrary length and puts the result +** into a third. 8192 bytes is enough for 1000!, beyond that +** the buffer-size may need to be incremented. +*/ diff --git a/reference/C/CONTRIB/SNIP/bincomp.c b/reference/C/CONTRIB/SNIP/bincomp.c new file mode 100755 index 0000000..15ad353 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/bincomp.c @@ -0,0 +1,172 @@ +/* +** BINCOMP -- binary compare +** by Raymond Gardner -- Englewood CO -- 8/92 -- public domain +*/ + +#include +#include +#include +#include + +#ifndef min +#define min(a,b) ((a) < (b) ? (a) : (b)) +#endif +#define bufsize 8 +#define empty_legend " .." + +unsigned char f1buf[bufsize+1], f2buf[bufsize+1]; +long prevn; + +void putempty(unsigned n) +{ + while (n--) + printf(empty_legend); +} + +void putbl(unsigned n) +{ + while (n--) + printf(" "); +} + +void showbufs(long n, unsigned m, unsigned char *b1, unsigned char *b2) +{ + unsigned i; + + if (n != prevn + bufsize) + printf("\n"); + prevn = n; + printf("%08lX ", n); + + if (b1 && b2) + { + for (i = 0; i < m; i++) + printf(" %02X", b1[i]); + for (i = m; i < 8; i++) + printf(" "); + putchar(' '); + for (i = 0; i < m; i++) + { + if (isprint(b1[i])) + putchar(b1[i]); + else putchar(' '); + } + for (i = m; i < 8; i++) + putchar(' '); + printf(" |"); + for (i = 0; i < m; i++) + { + if (b1[i] != b2[i]) + printf(" %02X", b2[i]); + else printf(empty_legend); + } + for (i = m; i < 8; i++) + printf(" "); + putchar(' '); + for (i = 0; i < m; i++) + { + if (b1[i] != b2[i] && isprint(b2[i])) + putchar(b2[i]); + else putchar(' '); + } + } + else if (b1) + { + for (i = 0; i < m; i++) + printf(" %02X", b1[i]); + for (i = m; i < 8; i++) + printf(" "); + putchar(' '); + for (i = 0; i < m; i++) + { + if (isprint(b1[i])) + putchar(b1[i]); + else putchar(' '); + } + for (i = m; i < 8; i++) + putchar(' '); + printf(" |"); + } + else + { + putbl(33); + printf(" |"); + for (i = 0; i < m; i++) + printf(" %02X", b2[i]); + for (i = m; i < 8; i++) + printf(" "); + putchar(' '); + for (i = 0; i < m; i++) + { + if (isprint(b2[i])) + putchar(b2[i]); + else putchar(' '); + } + } + printf("\n"); +} + +long fsize(FILE *fp) +{ + long pos, size; + + pos = ftell(fp); + fseek(fp, 0L, SEEK_END); + size = ftell(fp); + fseek(fp, pos, SEEK_SET); + return size; +} + +void bincomp(FILE *f1, FILE *f2) +{ + unsigned m; + long f1len, f2len, k, n; + + prevn = -1; + f1len = fsize(f1); + f2len = fsize(f2); + printf("%ld %ld\n", f1len, f2len); + k = min(f1len, f2len); + n = 0; + while (n < k) + { + m = (unsigned)min(k - n, (long)bufsize); + fread(f1buf, 1, m, f1); + fread(f2buf, 1, m, f2); + if (memcmp(f1buf, f2buf, m) != 0) + showbufs(n, m, f1buf, f2buf); + n += m; + } + while (n < f1len) + { + m = (unsigned)min(f1len - n, (long)bufsize); + fread(f1buf, 1, m, f1); + showbufs(n, m, f1buf, NULL); + n += m; + } + while (n < f2len) + { + m = (unsigned)min(f2len - n, (long)bufsize); + fread(f2buf, 1, m, f2); + showbufs(n, m, NULL, f2buf); + n += m; + } +} + +int main(int argc, char **argv) +{ + FILE *f1, *f2; + + if (argc < 3) + { + puts("Usage: bincomp f1 f2"); + exit(0); + } + printf("%s vs. %s\n", argv[1], argv[2]); + f1 = fopen(argv[1], "rb"); + f2 = fopen(argv[2], "rb"); + if (f1 && f2) + bincomp(f1, f2); + else puts("can't open file(s)"); + return 0; +} diff --git a/reference/C/CONTRIB/SNIP/biport.c b/reference/C/CONTRIB/SNIP/biport.c new file mode 100755 index 0000000..1b1e6bb --- /dev/null +++ b/reference/C/CONTRIB/SNIP/biport.c @@ -0,0 +1,16 @@ +/* +** BIPORT.C - Port TC/TC++/BC++ code using register pseudovariables +** +** public domain by Bob Stout +*/ + +#include "biport.h" + +union REGS BIP_regs_; +struct SREGS BIP_sregs_; + +unsigned _pascal geninterrupt(int int_no) +{ + int86x(int_no, &BIP_regs_, &BIP_regs_, &BIP_sregs_); + return BIP_regs_.x.ax; +} diff --git a/reference/C/CONTRIB/SNIP/biport.h b/reference/C/CONTRIB/SNIP/biport.h new file mode 100755 index 0000000..79fb14f --- /dev/null +++ b/reference/C/CONTRIB/SNIP/biport.h @@ -0,0 +1,34 @@ +/* +** BIPORT.H - Port TC/TC++/BC++ code using register pseudovariables +** +** public domain by Bob Stout +*/ + +#include + +extern union REGS BIP_regs_; +extern struct SREGS BIP_sregs_; + +#define _AX BIP_regs_.x.ax +#define _BX BIP_regs_.x.bx +#define _CX BIP_regs_.x.cx +#define _DX BIP_regs_.x.dx +#define _AH BIP_regs_.h.ah +#define _AL BIP_regs_.h.al +#define _BH BIP_regs_.h.ah +#define _BL BIP_regs_.h.al +#define _CH BIP_regs_.h.ah +#define _CL BIP_regs_.h.al +#define _DH BIP_regs_.h.ah +#define _DL BIP_regs_.h.al +#define _SI BIP_regs_.x.si +#define _DI BIP_regs_.x.di +#define _CF BIP_regs_.x.cflag +#define _FF BIP_regs_.x.flags +#define _ES BIP_sregs_.es +#define _CS BIP_sregs_.cs +#define _SS BIP_sregs_.ss +#define _DS BIP_sregs_.ds +#define regload_() segread(&BIP_sregs_) + +unsigned _pascal geninterrupt(int); diff --git a/reference/C/CONTRIB/SNIP/bitarray.c b/reference/C/CONTRIB/SNIP/bitarray.c new file mode 100755 index 0000000..3f09401 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/bitarray.c @@ -0,0 +1,15 @@ +char set[(BITCOUNT + 7) / 8]; + +int getbit(char *set, int number) +{ + set += number / 8; + return (*set & (1 << (number % 8))) != 0; /* 0 or 1 */ +} + +int setbit(char *set, int number, int value) +{ + set += number / 8; + if (value) + *set |= 1 << (number % 8); /* set bit */ + else *set &= ~(1 << (number % 8)); /* clear bit */ +} diff --git a/reference/C/CONTRIB/SNIP/bitcnt_1.c b/reference/C/CONTRIB/SNIP/bitcnt_1.c new file mode 100755 index 0000000..735c4e1 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/bitcnt_1.c @@ -0,0 +1,41 @@ +/* +** Bit counter by Ratko Tomic +*/ + +int bit_count(long x) +{ + int n = 0; +/* +** The loop will execute once for each bit of x set, this is in average +** twice as fast as the shift/test method. +*/ + if (x) do + n++; + while (0 != (x = x&(x-1))) + ; + return(n); +} + +#ifdef TEST + +#include +#include + +#define plural_text(n) &"s"[(1 == (n))] + +void main(int argc, char *argv[]) +{ + long n; + + while(--argc) + { + int i; + + n = atol(*++argv); + i = bit_count(n); + printf("%ld contains %d bit%s set\n", + n, i, plural_text(i)); + } +} + +#endif /* TEST */ diff --git a/reference/C/CONTRIB/SNIP/bitcnt_2.c b/reference/C/CONTRIB/SNIP/bitcnt_2.c new file mode 100755 index 0000000..9046456 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/bitcnt_2.c @@ -0,0 +1,33 @@ +int bitcount(long i) +{ + i = ((i & 0xAAAAAAAA) >> 1) + (i & 0x55555555); + i = ((i & 0xCCCCCCCC) >> 2) + (i & 0x33333333); + i = ((i & 0xF0F0F0F0) >> 4) + (i & 0x0F0F0F0F); + i = ((i & 0xFF00FF00) >> 8) + (i & 0x00FF00FF); + i = ((i & 0xFFFF0000) >> 16) + (i & 0x0000FFFF); + return (int)i; +} + +#ifdef TEST + +#include +#include + +#define plural_text(n) &"s"[(1 == (n))] + +void main(int argc, char *argv[]) +{ + long n; + + while(--argc) + { + int i; + + n = atol(*++argv); + i = bitcount(n); + printf("%ld contains %d bit%s set\n", + n, i, plural_text(i)); + } +} + +#endif /* TEST */ diff --git a/reference/C/CONTRIB/SNIP/bitfiles.c b/reference/C/CONTRIB/SNIP/bitfiles.c new file mode 100755 index 0000000..ef27e77 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/bitfiles.c @@ -0,0 +1,138 @@ +/* +** BITFILES.C - reading/writing bit files +** +** Public domain by Aare Tali +*/ + +#include +#include + +typedef struct { + FILE * file; /* for stream I/O */ + char rbuf; /* read bit buffer */ + char rcnt; /* read bit count */ + char wbuf; /* write bit buffer */ + char wcnt; /* write bit count */ +} bfile; + +bfile *bfopen(char *name, char *mode) +{ + bfile * bf; + + bf = malloc(sizeof(bfile)); + if (NULL == bf) + return NULL; + bf->file = fopen(name, mode); + if (NULL == bf->file) + { + free(bf); + return NULL; + } + bf->rcnt = 0; + bf->wcnt = 0; + return bf; +} + +int bfread(bfile *bf) +{ + if (0 == bf->rcnt) /* read new byte */ + { + bf->rbuf = (char)fgetc(bf->file); + bf->rcnt = 8; + } + bf->rcnt--; + return (bf->rbuf & (1 << bf->rcnt)) != 0; +} + +void bfwrite(int bit, bfile *bf) +{ + if (8 == bf->wcnt) /* write full byte */ + { + fputc(bf->wbuf, bf->file); + bf->wcnt = 0; + } + bf->wcnt++; + bf->wbuf <<= 1; + bf->wbuf |= bit & 1; +} + +void bfclose(bfile *bf) +{ + fclose(bf->file); + free(bf); +} + +void test1(void) +{ + bfile *out; + bfile *in; + FILE *in1; + FILE *in2; + + in = bfopen("bitfiles.c", "rb"); + out = bfopen("bitfiles.cc", "wb"); + if ((NULL == in) || (NULL == out)) + { + printf("Can't open/create test files\n"); + exit(1); + } + while (!feof(in->file)) + bfwrite(bfread(in), out); + bfclose(in); + bfclose(out); + in1 = fopen("bitfiles.c", "rb"); + in2 = fopen("bitfiles.cc", "rb"); + if ((NULL == in1) || (NULL == in2)) + { + printf("Can't open test files for verifying\n"); + exit(1); + } + while (!feof(in1) && !feof(in2)) + { + if (fgetc(in1) != fgetc(in2)) + { + printf("Files not identical, copy failed!\n"); + exit(1); + } + } + if (!feof(in1) || !feof(in2)) + { + printf("Not same size, copy failed!\n"); + exit(1); + } + fclose(in1); + fclose(in2); +} + +void test2(void) +{ + FILE *in1; + bfile *in2; + int ch; + + in1 = fopen("bitfiles.c", "rb"); + in2 = bfopen("bitfiles.cc", "rb"); + if ((NULL == in1) || (NULL == in2)) + { + printf("Can't open test files\n"); + exit(1); + } + while (!feof(in1) && !feof(in2->file)) + { + ch = fgetc(in1); + if (ch < ' ') + ch = '.'; + printf(" '%c' ", ch); + for (ch = 0; ch < 8; ch++) + printf("%c", "01"[bfread(in2)]); + printf(" "); + } + fclose(in1); + bfclose(in2); +} + +void main(void) +{ + test1(); + test2(); +} diff --git a/reference/C/CONTRIB/SNIP/bitops.c b/reference/C/CONTRIB/SNIP/bitops.c new file mode 100755 index 0000000..1d0c0bc --- /dev/null +++ b/reference/C/CONTRIB/SNIP/bitops.c @@ -0,0 +1,13 @@ +/* +** Bit set, clear, and test operations +** +** public domain snippet by Bob Stout +*/ + +typedef enum {ERROR = -1, FALSE, TRUE} LOGICAL; + +#define BOOL(x) (!(!(x))) + +#define BitSet(arg,posn) ((arg) | (1L << (posn))) +#define BitClr(arg,posn) ((arg) & ~(1L << (posn))) +#define BitTst(arg,posn) BOOL((arg) & (1L << (posn))) diff --git a/reference/C/CONTRIB/SNIP/bitstrng.c b/reference/C/CONTRIB/SNIP/bitstrng.c new file mode 100755 index 0000000..8c72768 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/bitstrng.c @@ -0,0 +1,59 @@ +/* +** bitstring(): print bit pattern of bytes formatted to string. +** +** By J. Blauth, Sept. 1992. Hereby placed into the public domain. +** +** byze: value to transform to bitstring. +** biz: count of bits to be shown (counted from lowest bit, can be any +** even or odd number). +** strwid: total width the string shall have. Since between every 4 bits a +** blank (0x20) is inserted (not added after lowest bit), width of +** bitformat only is (biz+(biz/4-1)). Bits are printed right aligned, +** positions from highest bit to start of string filled with blanks. +** If value of strwid smaller than space needed to print all bits, +** strwid is ignored (e.g.: +** bitstr(s,b,16,5) results in 19 chars +'\0'). +** +** EXAMPLE: +** for (j = 1; j <= 16; j++) { bitstring(s, j, j, 16); puts(s); } +** 1: 1 +** 2: 10 +** 3: 011 +** d: 0 0000 0000 1101 +** e: 00 0000 0000 1110 +** f: 000 0000 0000 1111 +*/ + +void bitstring(char *str, long byze, int biz, int strwid) +{ + int i, j; + + j = strwid - (biz + (biz >> 2)- (biz % 4 ? 0 : 1)); + for (i = 0; i < j; i++) + *str++ = ' '; + while (--biz >= 0) + { + *str++ = ((byze >> biz) & 1) + '0'; + if (!(biz % 4) && biz) + *str++ = ' '; + } + *str = '\0'; +} + +#ifdef TEST + +#include +#include + +int main(void) +{ + char s[80]; long j; + for (j = 1L; j <= 16L; j++) + { + bitstring(s, (long)j, (int)j, 16); + printf("%2ld: %s\n", j, s); + } + return EXIT_SUCCESS; +} + +#endif diff --git a/reference/C/CONTRIB/SNIP/bmhasrch.c b/reference/C/CONTRIB/SNIP/bmhasrch.c new file mode 100755 index 0000000..6eb21da --- /dev/null +++ b/reference/C/CONTRIB/SNIP/bmhasrch.c @@ -0,0 +1,104 @@ +/* +** Boyer-Moore-Horspool pattern match +** Case-insensitive with accented character translation +** +** public domain by Raymond Gardner 7/92 +** +** limitation: pattern length + subject length must be less than 32767 +** +** 10/21/93 rdg Fixed bug found by Jeff Dunlop +*/ +#include /* rdg 10/93 */ +#include +#include + +typedef unsigned char uchar; + +#define LOWER_ACCENTED_CHARS + +unsigned char lowervec[UCHAR_MAX+1] = { /* rdg 10/93 */ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32,'!','"','#','$','%','&','\'','(',')','*','+',',','-','.','/', +'0','1','2','3','4','5','6','7','8','9',':',';','<','=','>','?', +'@','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o', +'p','q','r','s','t','u','v','w','x','y','z','[','\\',']','^','_', +'`','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o', +'p','q','r','s','t','u','v','w','x','y','z','{','|','}','~',127, +#ifdef LOWER_ACCENTED_CHARS +'c','u','e','a','a','a','a','c','e','e','e','i','i','i','a','a', +'e',145,146,'o','o','o','u','u','y','o','u',155,156,157,158,159, +'a','i','o','u','n','n',166,167,168,169,170,171,172,173,174,175, +#else +128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, +144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159, +160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175, +#endif +176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191, +192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207, +208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223, +224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239, +240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255, +}; + +#define lowerc(c) lowervec[(uchar)(c)] + +#define LARGE 32767 + +static int patlen; +static int skip[UCHAR_MAX+1]; /* rdg 10/93 */ +static int skip2; +static uchar *pat; + +void bmh_init(const char *pattern) +{ + int i, j; + pat = (uchar *)pattern; + patlen = strlen(pattern); + for (i = 0; i <= UCHAR_MAX; ++i) /* rdg 10/93 */ + { + skip[i] = patlen; + for (j = patlen - 1; j >= 0; --j) + { + if (lowerc(i) == lowerc(pat[j])) + break; + } + if (j >= 0) + skip[i] = patlen - j - 1; + if (j == patlen - 1) + skip[i] = LARGE; + } + skip2 = patlen; + for (i = 0; i < patlen - 1; ++i) + { + if ( lowerc(pat[i]) == lowerc(pat[patlen - 1]) ) + skip2 = patlen - i - 1; + } +} + +char *bmh_search(const char *string, const int stringlen) +{ + int i, j; + char *s; + + i = patlen - 1 - stringlen; + if (i >= 0) + return NULL; + string += stringlen; + for ( ;; ) + { + while ((i += skip[((uchar *)string)[i]]) < 0) + ; /* mighty fast inner loop */ + if (i < (LARGE - stringlen)) + return NULL; + i -= LARGE; + j = patlen - 1; + s = (char *)string + (i - j); + while (--j >= 0 && lowerc(s[j]) == lowerc(pat[j])) + ; + if ( j < 0 ) /* rdg 10/93 */ + return s; /* rdg 10/93 */ + if ( (i += skip2) >= 0 ) /* rdg 10/93 */ + return NULL; /* rdg 10/93 */ + } +} diff --git a/reference/C/CONTRIB/SNIP/bmhisrch.c b/reference/C/CONTRIB/SNIP/bmhisrch.c new file mode 100755 index 0000000..13a6655 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/bmhisrch.c @@ -0,0 +1,94 @@ +/* +** Case-Insensitive Boyer-Moore-Horspool pattern match +** +** Public Domain version by Thad Smith 7/21/1992, +** based on a 7/92 public domain BMH version by Raymond Gardner. +** +** This program is written in ANSI C and inherits the compilers +** ability (or lack thereof) to support non-"C" locales by use of +** toupper() and tolower() to perform case conversions. +** Limitation: pattern length + string length must be less than 32767. +** +** 10/21/93 rdg Fixed bugs found by Jeff Dunlop +*/ + +#include +#include +#include +#include + +typedef unsigned char uchar; + +#define LARGE 32767 /* flag for last character match */ + +static int patlen; /* # chars in pattern */ +static int skip[UCHAR_MAX+1]; /* skip-ahead count for test chars */ +static int skip2; /* skip-ahead after non-match with + ** matching final character */ +static uchar *pat = NULL; /* uppercase copy of pattern */ + +/* +** bmhi_init() is called prior to bmhi_search() to calculate the +** skip array for the given pattern. +** Error: exit(1) is called if no memory is available. +*/ + +void bmhi_init(const char *pattern) +{ + int i, lastpatchar; + patlen = strlen(pattern); + + /* Make uppercase copy of pattern */ + + pat = realloc ((void*)pat, patlen); + if (!pat) + exit(1); + for (i=0; i < patlen; i++) + pat[i] = toupper(pattern[i]); + + /* initialize skip array */ + + for ( i = 0; i <= UCHAR_MAX; ++i ) /* rdg 10/93 */ + skip[i] = patlen; + for ( i = 0; i < patlen - 1; ++i ) + { + skip[ pat[i] ] = patlen - i - 1; + skip[tolower(pat[i])] = patlen - i - 1; + } + lastpatchar = pat[patlen - 1]; + skip[ lastpatchar ] = LARGE; + skip[tolower(lastpatchar)] = LARGE; + skip2 = patlen; /* Horspool's fixed second shift */ + for (i = 0; i < patlen - 1; ++i) + { + if ( pat[i] == lastpatchar ) + skip2 = patlen - i - 1; + } +} + +char *bmhi_search(const char *string, const int stringlen) +{ + int i, j; + char *s; + + i = patlen - 1 - stringlen; + if (i >= 0) + return NULL; + string += stringlen; + for ( ;; ) + { + while ( (i += skip[((uchar *)string)[i]]) < 0 ) + ; /* mighty fast inner loop */ + if (i < (LARGE - stringlen)) + return NULL; + i -= LARGE; + j = patlen - 1; + s = (char *)string + (i - j); + while ( --j >= 0 && toupper(s[j]) == pat[j] ) + ; + if ( j < 0 ) /* rdg 10/93 */ + return s; /* rdg 10/93 */ + if ( (i += skip2) >= 0 ) /* rdg 10/93 */ + return NULL; /* rdg 10/93 */ + } +} diff --git a/reference/C/CONTRIB/SNIP/bmhsrch.c b/reference/C/CONTRIB/SNIP/bmhsrch.c new file mode 100755 index 0000000..37aa98a --- /dev/null +++ b/reference/C/CONTRIB/SNIP/bmhsrch.c @@ -0,0 +1,68 @@ +/* +** Case-sensitive Boyer-Moore-Horspool pattern match +** +** public domain by Raymond Gardner 7/92 +** +** limitation: pattern length + string length must be less than 32767 +** +** 10/21/93 rdg Fixed bug found by Jeff Dunlop +*/ +#include /* rdg 10/93 */ +#include +#include + +typedef unsigned char uchar; + +#define LARGE 32767 + +static int patlen; +static int skip[UCHAR_MAX+1]; /* rdg 10/93 */ +static int skip2; +static uchar *pat; + +void bmh_init(const char *pattern) +{ + int i, lastpatchar; + + pat = (uchar *)pattern; + patlen = strlen(pattern); + for (i = 0; i <= UCHAR_MAX; ++i) /* rdg 10/93 */ + skip[i] = patlen; + for (i = 0; i < patlen; ++i) + skip[pat[i]] = patlen - i - 1; + lastpatchar = pat[patlen - 1]; + skip[lastpatchar] = LARGE; + skip2 = patlen; /* Horspool's fixed second shift */ + for (i = 0; i < patlen - 1; ++i) + { + if (pat[i] == lastpatchar) + skip2 = patlen - i - 1; + } +} + +char *bmh_search(const char *string, const int stringlen) +{ + int i, j; + char *s; + + i = patlen - 1 - stringlen; + if (i >= 0) + return NULL; + string += stringlen; + for ( ;; ) + { + while ( (i += skip[((uchar *)string)[i]]) < 0 ) + ; /* mighty fast inner loop */ + if (i < (LARGE - stringlen)) + return NULL; + i -= LARGE; + j = patlen - 1; + s = (char *)string + (i - j); + while (--j >= 0 && s[j] == pat[j]) + ; + if ( j < 0 ) /* rdg 10/93 */ + return s; /* rdg 10/93 */ + if ( (i += skip2) >= 0 ) /* rdg 10/93 */ + return NULL; /* rdg 10/93 */ + } +} diff --git a/reference/C/CONTRIB/SNIP/bordcolr.c b/reference/C/CONTRIB/SNIP/bordcolr.c new file mode 100755 index 0000000..8f441ff --- /dev/null +++ b/reference/C/CONTRIB/SNIP/bordcolr.c @@ -0,0 +1,109 @@ +/* +** BORDCOLR.C - set the border color +** by: Bob Jarvis +*/ + +#include +#include +#include + +char *usage = "BORDCOLR - sets the border color\n" + "Parameter: color to set - one of\n" + "\tBLK - black\n" + "\tBLU - blue\n" + "\tGRN - green\n" + "\tCYN - cyan\n" + "\tRED - red\n" + "\tMAG - magenta\n" + "\tBRN - brown\n" + "\tLTG - light gray\n" + "\tDKG - dark gray\n" + "\tLTB - light blue\n" + "\tLGN - light green\n" + "\tLTC - light cyan\n" + "\tLTR - light red\n" + "\tLTM - light magenta\n" + "\tYEL - yellow\n" + "\tWHT - white"; + +#define BLACK 0 +#define BLUE 1 +#define GREEN 2 +#define CYAN 3 +#define RED 4 +#define MAGENTA 5 +#define BROWN 6 +#define LTGRAY 7 +#define DKGRAY 8 +#define LTBLUE 9 +#define LTGREEN 10 +#define LTCYAN 11 +#define LTRED 12 +#define LTMAGENTA 13 +#define YELLOW 14 +#define WHITE 15 + +void set_border_color(int color) +{ + union REGS regs; + + printf("color = %d\n", color); + + regs.h.ah = 0x0B; + regs.h.bh = 0; + regs.h.bl = color; + + int86(0x10, ®s, ®s); +} + +main(int argc, char *argv[]) +{ + int color; + + if(argc < 2) + { + printf(usage); + return EXIT_SUCCESS; + } + + if(strcmpl(argv[1], "BLK") == 0) + color = BLACK; + else if(strcmpl(argv[1], "BLU") == 0) + color = BLUE; + else if(strcmpl(argv[1], "GRN") == 0) + color = GREEN; + else if(strcmpl(argv[1], "CYN") == 0) + color = CYAN; + else if(strcmpl(argv[1], "RED") == 0) + color = RED; + else if(strcmpl(argv[1], "MAG") == 0) + color = MAGENTA; + else if(strcmpl(argv[1], "BRN") == 0) + color = BROWN; + else if(strcmpl(argv[1], "LTG") == 0) + color = LTGRAY; + else if(strcmpl(argv[1], "DKG") == 0) + color = DKGRAY; + else if(strcmpl(argv[1], "LTB") == 0) + color = LTBLUE; + else if(strcmpl(argv[1], "LGN") == 0) + color = LTGREEN; + else if(strcmpl(argv[1], "LTC") == 0) + color = LTCYAN; + else if(strcmpl(argv[1], "LTR") == 0) + color = LTRED; + else if(strcmpl(argv[1], "LTM") == 0) + color = LTMAGENTA; + else if(strcmpl(argv[1], "YEL") == 0) + color = YELLOW; + else if(strcmpl(argv[1], "WHT") == 0) + color = WHITE; + else + { + printf(usage); + return EXIT_SUCCESS; + } + + set_border_color(color); + return EXIT_SUCCESS; +} diff --git a/reference/C/CONTRIB/SNIP/break.c b/reference/C/CONTRIB/SNIP/break.c new file mode 100755 index 0000000..6334255 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/break.c @@ -0,0 +1,29 @@ +/* +** Set or determine the status of the DOS "SET BREAK=" command +*/ + +#include + +#define BOOL(x) (!(!(x))) + +/* +** Returns status of DOS "SET BREAK" command +*/ + +int isBreakOn(void) +{ + union REGS regs; + + regs.x.ax = 0x3300; + intdos(®s, ®s); + return (int)regs.h.dl; +} + +void setBreak(int OnOff) /* Off = 0, On = 1 */ +{ + union REGS regs; + + regs.x.ax = 0x3301; + regs.h.dl = OnOff; + intdos(®s, ®s); +} diff --git a/reference/C/CONTRIB/SNIP/bresnham.c b/reference/C/CONTRIB/SNIP/bresnham.c new file mode 100755 index 0000000..6bfc344 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/bresnham.c @@ -0,0 +1,155 @@ +/* +** Public Domain mode 13h Bresenham line/circle algorithms +** By Brian Dessent +** +** Written for Borland, modified for others by Bob Stout +*/ + +#include +#include +#include +#include +#include /* for randomize */ + +#ifndef __TURBOC__ + #define random(num) (int)(((rand())*(long)(num))/(((long)RAND_MAX)+1)) + #define randomize() srand((unsigned)time(NULL)|1) +#else +#endif + +#ifndef MK_FP + #define MK_FP(seg,offset) \ + ((void far *)(((unsigned long)(seg)<<16) | (unsigned)(offset))) +#endif + +#define SCREEN_WIDTH 320 +#define SCREEN_HEIGTH 200 +#define MAX_X (SCREEN_WIDTH-1) +#define MAX_Y (SCREEN_HEIGTH-1) + +/* prototypes */ + +void setmode(int mode); +void plotdot(int x, int y, char c); +void bresenham_line(int x, int y, int x2, int y2, char c); +void bresenham_circle(int xc, int yc, int r, char c); +void main(void); + +/* code begins */ + +/* uses BIOS to set video mode */ + +void setmode(int mode) +{ + union REGS r; + + r.x.ax = mode; + int86(0x10, &r, &r); +} + + +/* plots a dot at (x, y) with color c */ + +void plotdot(int x, int y, char c) +{ + register char far *addr; + + if(x < 0 || x > MAX_X || y < 0 || y > MAX_Y) + return; + + addr = MK_FP(0xa000, (SCREEN_WIDTH * y) + x); + *addr = c; +} + + +/* draws a line from (x, y) to (x2, y2) in color c */ + +void bresenham_line(int x, int y, int x2, int y2, char c) +{ + int i, steep = 0, sx, sy, dx, dy, e; + + dx = abs(x2 - x); + sx = ((x2 - x) > 0) ? 1 : -1; + dy = abs(y2 - y); + sy = ((y2 - y) > 0) ? 1 : -1; + + if(dy > dx) + { + steep = 1; + x ^= y; /* swap x and y */ + y ^= x; + x ^= y; + dx ^= dy; /* swap dx and dy */ + dy ^= dx; + dx ^= dy; + sx ^= sy; /* swap sx and sy */ + sy ^= sx; + sx ^= sy; + } + + e = 2 * dy - dx; + for(i = 0;i < dx;i++) + { + if(steep) + plotdot(y, x, c); + else plotdot(x, y, c); + while(e >= 0) + { + y += sy; + e -= 2 * dx; + } + x += sx; + e += 2 * dy; + } + plotdot(x2, y2, c); +} + +/* draws a circle at (xc, yc) with radius r in color c +** +** note: the scaling factor of (SCREEN_WIDTH / SCREEN_HEIGTH) is used when +** updating d. This makes round circles. If you want ellipses, you can +** modify that ratio. +*/ + +void bresenham_circle(int xc, int yc, int r, char c) +{ + int x = 0, y = r, d = 2 * (1 - r); + + while(y > 0) + { + plotdot(xc + x, yc + y, c); + plotdot(xc + x, yc - y, c); + plotdot(xc - x, yc + y, c); + plotdot(xc - x, yc - y, c); + if(d + y > 0) + { + y -= 1; + d -= (2 * y * SCREEN_WIDTH / SCREEN_HEIGTH) - 1; + } + if(x > d) + { + x += 1; + d += (2 * x) + 1; + } + } +} + +/* draws random lines and circles until a key is pressed in mode 13h */ +/* (draws in colors 0 - 63 only) */ + +void main(void) +{ + int i=0; + + randomize(); + setmode(0x13); + while(!kbhit()) + { + bresenham_line(random(SCREEN_WIDTH), random(SCREEN_HEIGTH), + random(SCREEN_WIDTH), random(SCREEN_HEIGTH), i = ++i % 64); + bresenham_circle(random(SCREEN_WIDTH), random(SCREEN_HEIGTH), + random(50), i = ++i % 64); + } + getch(); + setmode(0x03); /* set to color text mode, clearing screen */ +} diff --git a/reference/C/CONTRIB/SNIP/bstr_i.c b/reference/C/CONTRIB/SNIP/bstr_i.c new file mode 100755 index 0000000..94255e1 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/bstr_i.c @@ -0,0 +1,40 @@ +/* +** Make an ascii binary string into an integer. +** +** Public domain by Bob Stout +*/ + +#include + +unsigned int bstr_i(char *cptr) +{ + unsigned int i, j = 0; + + while (cptr && *cptr && strchr("01", *cptr)) + { + i = *cptr++ - '0'; + j <<= 1; + j |= (i & 0x01); + } + return(j); +} + +#ifdef TEST + +#include +#include + +int main(int argc, char *argv[]) +{ + char *arg; + unsigned int x; + + while (--argc) + { + x = bstr_i(arg = *++argv); + printf("Binary %s = %d = %04Xh\n", arg, x, x); + } + return EXIT_SUCCESS; +} + +#endif /* TEST */ diff --git a/reference/C/CONTRIB/SNIP/c_cmnt.c b/reference/C/CONTRIB/SNIP/c_cmnt.c new file mode 100755 index 0000000..d2df7c3 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/c_cmnt.c @@ -0,0 +1,154 @@ +/* Extract comments from a C program source file. +** +** This program acts as a filter to copy comments in a C source +** file to the output. Each comment includes the starting and +** ending delimiters and is followed by a newline. +** +** Three #ifdef options are defined: +** INHIBIT_TRIGRAPHS prevents recognition of trigraphs, which +** can affect detection of escaped characters, +** i.e., ??/" is an escaped quote. +** TRANSLATE_TRIGRAPHS causes the output to have trigraphs +** converted to the normal C characters. +** CPP_MODE causes "//" to start a comment. +** The default for these symbols is undefined, resulting in +** operation on strict ANSI source, except as noted below. +** +** What makes this program interesting is that comment detection +** should be inhibited within strings and character constants. +** +** Note: The name of a header following #include can, under ANSI, +** contain any sequence of characters, except \n and the closing +** > or ". This program doesn't inhibit comment, string, or character +** constant detection within the header name, as an ANSI parser must. +** +** Written by and contributed to the public domain by +** Thad Smith III, Boulder, CO, October 1990. +*/ + +#include + +#ifndef INHIBIT_TRIGRAPHS /* default: recognize trigraphs */ + #define getnc() getnsc(1) /* get char with trigraph xlate */ + #ifdef TRANSLATE_TRIGRAPHS + #define getcmtc() getnsc(1) /* get comment char w/ t.g. xlate */ + #else + #define getcmtc() getnsc(0) /* default: no comment t.g. xlate */ + #endif + +/* +** get next source character or EOF +*/ + +int getnsc(int cvtg) /* boolean: convert trigraphs */ +{ + static int c, nc, nnc; /* next 3 characters */ + + /* shift in next source character */ + + c = nc; nc = nnc; nnc = getchar(); + + /* perform trigraph substitution */ + + if (cvtg && c == '?' && nc == '?') + { + switch (nnc) + { + case '=' : + c = '#' ; + break; + case '(' : + c = '[' ; + break; + case '/' : + c = '\\'; + break; + case ')' : + c = ']' ; + break; + case '\'': + c = '^' ; + break; + case '<' : + c = '{' ; + break; + case '!' : + c = '|' ; + break; + case '>' : + c = '}' ; + break; + case '-' : + c = '~' ; + break; + default : + return c; /* no substitution */ + } + nc = getchar(); nnc = getchar(); + } + return c; +} + +#else /* don't process trigraphs */ + + #define getnc() getchar() + #define getcmtc() getchar() +#endif + +int main(void) +{ + int pc; /* previous character */ + int c; /* current input character */ + +#ifndef INHIBIT_TRIGRAPHS + getnc(); /* prime the pump */ + getnc(); +#endif + c = getnc(); /* get first char */ + + for (;;) /* in non-comment area */ + { + switch (c) + { + case '/': /* possible start of comment */ + if ((c= getnc()) == '*') /* process comment */ + { + putchar('/'); + putchar('*'); + + /* copy comment to stdout */ + + for (pc = 0; (c = getcmtc()) != EOF && + (putchar(c) != '/' || pc != '*'); pc=c) + ; + putchar('\n'); +#ifdef CPP_MODE + } + else if (c == '/') /* '//' comment */ + { + putchar('/'); + putchar('/'); + while ((c = getcmtc()) != EOF && putchar(c) != '\n') + ; +#endif + } + else continue; /* test current char */ + break; + + case '\"': /* start of string */ + case '\'': /* start of (possibly multi-byte) char constant */ + pc = c; /* save delimiter */ + do /* scan through character constant, + ** discarding escape chars + */ + { + while ((c = getnc()) == '\\') + getnc(); + } while (c != pc && c != EOF); + break; + } + if (c == EOF) + return 0; + else c = getnc(); + } +} diff --git a/reference/C/CONTRIB/SNIP/c_lines.awk b/reference/C/CONTRIB/SNIP/c_lines.awk new file mode 100755 index 0000000..219138c --- /dev/null +++ b/reference/C/CONTRIB/SNIP/c_lines.awk @@ -0,0 +1,43 @@ +# count lines in a C program, not counting comments, blank lines or +# form feeds +# does separate count of preprocessor directives +# if a preprocessor directive is commented out, it does not count +# +# By: Dan Kozak + +{ + if (file == "") { + file = FILENAME + } + if (file != FILENAME) { + printf("Number of lines in %s is: %d\n",file,nl+ppd) + printf("Number of preprocessor directives is: %d\n",ppd) + printf("Number of lines excluding preprocessor directives is: %d\n\n",nl) + file = FILENAME + tnl += nl + tppd += ppd + nl = 0 + ppd = 0 + } + + if ($0 == "") { ; } + else if ($1 ~ /^\/\*/ && $NF ~ /\*\/$/) { ; } + else if ($0 ~ /\/\*/ && $0 !~ /\*\//) { in_comment = 1 } + else if ($0 !~ /\/\*/ && $0 ~ /\*\//) { in_comment = 0 } + else if (in_comment) { ; } + else if ($1 ~ /^#/) { ppd++ } + else { nl++ } +} + +END { printf("Number of lines in %s is: %d\n",file,nl+ppd) + printf("Number of preprocessor directives is: %d\n",ppd) + printf("Number of lines excluding preprocessor directives is: +%d\n\n",nl) + file = FILENAME + tnl += nl + tppd += ppd + printf("Total number of lines is: %d\n",tnl+tppd) + printf("Number of preprocessor directives is: %d\n",tppd) + printf("Number of lines excluding preprocessor directives is: +%d\n",tnl) + } diff --git a/reference/C/CONTRIB/SNIP/c_port.txt b/reference/C/CONTRIB/SNIP/c_port.txt new file mode 100755 index 0000000..bc78baa --- /dev/null +++ b/reference/C/CONTRIB/SNIP/c_port.txt @@ -0,0 +1,340 @@ + +=====[ Ed Hopper's BBS #1 ]=====[ 8-04-91 ]=====[ 9:55.22 ]===== + + +Date: 08-02-91 (09:40) C-Lang Number: 26406 (Echo) + To: ALL +From: JOSEPH CARNAGE Read: 08-03-91 (10:56) +City: DUNEDIN FL Last On: 02-28-91 (22:53) +Subj: Portable, clean code #1 + + How to write portable clean source code + --------------------------------------- + +A common concern with programmers new to Axiom is writing portable +code. There a number of tricks and guide lines which may help with +this. In no particular order: + + -- Use full ANSI prototypes with all arguments declared. For + function pointers, declare their expected arguments. For + prototypes for functions which accept function pointers, do not + declare the expected arguments for the function pointer + argument. + + It is good practice to put dummy variable names in prototypes as + this adds readability. + + -- Explicitly type all variables and functions. Never rely on them + defaulting to int. + + -- Pay a little care to the ternary operator ? :, and parenthesize + heavily. A very few compilers have problems with the default + order of evaluation for the ternary operator. + + -- Never ever name a variable identically to a function. This is + most especially true of statics or globals. This sort of error + can cause weird hidden linker problems which cause bizarre + results at runtime and are difficult to trace. + + -- Never ever name a screen, form, data field etc identically to a + variable or function as this can cause weird and non-reported + linker errors in the final executable which can be very + difficult to locate. + + -- Do not nest comments. If you want to block off a section of + code temporarily, use #ifdef/#endif. eg. + + ...code... + #ifdef JUNK /* Unwanted code */ + ...more code... + #endif /* JUNK */ + ...yet more code... + + -- Run PC-Lint on all code, and handle ALL errors and warnings. + + -- Read the "Frequently Asked Questions" document and understand + fully. + + -- Read K&R thoroughly and everywhere it mentions "implementation + dependant", or "new" features not "supported by all compilers", + avoid those areas. Examples are bit fields, passing structures + to functions, returning structures from functions, and the + volatile type. These are not supported by all compilers. + + -- In areas where the ANSI standard advances on the old K&R, but + still allows the K&R form, follow K&R. An example is using + function pointers. If you are unsure what areas this covers, + don't worry, just stick with K&R. eg. + + Given: + + int (*prj_afunc) (); /* Pointer to function which returns int */ + + ANSI allows the pointed to function be called as so: + + prj_afunc (xxx, yyy); + + K&R specifies that it should be called: + + *prj-afunc (xxx, yyy); + + Use the K&R form, which ANSI still allows, and all compilers + support. + + -- Do not use the new // comments. Stay with the /* comment */ + form. + + -- Do not indent #ifdefs, #defines, #pragmas, or other preprocessor + directives. Some compilers allow code as such: + + #ifdef DEBUG + #define TEST 1 + #endif + + or + + #ifdef FINAL + # ifdef DEBUG + # define TEST 1 + # endif + #endif + + But by no means all. Use white space if needed to delineate + #ifdef/endif blocks and comment liberally: + + #ifdef FINAL + + #ifdef DEBUG + #define TEST 1 + #endif /* DEBUG*/ + + #endif /* FINAL */ + + -- Do not use the ANSI string literal concatenation features. eg. + + printf ("This is ANSI but" + "unportable code.\n"); + + for long string literals. Under ANSI the the compiler should + concatenate the two string literals into one, but not all ANSI + compilers support this feature yet. If you need a very long + string literal use a form as so: + + printf ("%s%s", + "this is", + "portable code.\n"); + + or just use a very long string literal. + + -- Stay away from ints except for trash and temp values. Ints vary + in size depending upon the memory model under DOS, and legally + may be any size between shorts and longs inclusive. + + Try to use shorts or longs if possible, as these are of fairly + constant size on most platforms. On most platforms, but by no + means all, shorts are usually words and longs word pairs. + + -- Beware of assigning a pointer of one type to a pointer of a + higher type. Most platforms seem to insist that the addresses + stored in pointers are alligned per the pointer's base type. + + What this means is that the value stored in a pointer to a long, + in itself will be alligned as a long is. If longs are alligned + on even word boundaries, then so will the value of long pointer. + + This can result in memory allignment errors which can be + extremely difficult to track down. Casting will not help. + + DOS has few memory allignment requirements, but for Unix and VMS + you can expect types to be alligned to their sizes (see the + compiler manuals for specifics). What this means to pointers is + that with code such as: + + short *pj2_value; /* Assume that shorts are alligned to words */ + long *pj4_number; /* and longs to even word boundaries */ + + pj4_number = pj2_value; + + that the value assigned to pj4_number may be as far as two bytes + different from that in pj2_value. ie + + Let's say that the address stored is pj2_value is: + + *pj2_value == 0000:0006 /* Alligned to word */ + + and you make the assignment: + + pj4_number = pj2_value; + + After this, the value of pj4_number will be either 0000:0004, + or 0000:0008 to shift it to even word allignment. The + direction of the shift seems to be compiler/implementation + dependant. + + This bug is often erratic at runtime depending upon the + allignment of automatics. This sort of bug is especically + difficult to track when coming up from a void pointer. + + -- Be wary of relying on memory allignment in structures and + unions. Different compiler implmentations allign differently, + and #pragmas or command line arguments to the compiler can + change allignment at compile time. See the compiler manuals for + specific details. + + This will usually require you to either read in each member + individually, or to perform explicit padding when reading + structure data from disk. eg. lic1.c & v_lic_pad() in the Axiom + library. + + -- Where possible use sizeof(identifier) rather than sizeof(type) + or a #defined constant. This can help in tracing down bugs and + makes for greater readability. eg. + + #define M_DATA 100 + short aj2_numbers[M_DATA]; + + /* This example requires the reader to remember that + aj2_numbers has M_DATA elements, is overly complex, and + presumes that aj2_numbers will always be shorts. This code + will likely break if anything is later changed. */ + + memcpy (aj2_numbers, pj2_input, M_DATA * sizeof (short)); + + /* This is ideal -- sizeof(aj2_numbers) will return the total + space allocated to the array, no matter what the type may be, + or what is changed later. It makes no assumptions of the + reader. */ + + memcpy (aj2_numbers, pj2_input, sizeof (aj2_numbers)); + + -- Beware of comparing structures or unions with functions such as + memcmp() as the padding/allignment spaces will have random and + likely different values. If you need to compare structures + you'll have to do it member by member. + + -- Never assign structures to each other directly. Some compilers + allow structure assignments, some don't. + + struct t_data s_struc1; + struct t_data s_struc2; + + s_struc2 = s_struc1; /* Unportable code */ + + Note however that you can copy structures via pointers as need + be: + + struct t_data *ps_struc1; + struct t_data *ps_struc2; + + ps_struc1 = xxx; + ps_struc2 = yyy; + + *ps_struc2 = *ps_struc1; /* Copy structure 1 to 2 */ + + Rather than assigning each member over individually. The + functions memcpy() and memmove() are other portable ways. + + -- Beware of passing chars or shorts to functions. These get + promoted to ints, and with some compilers problems from there on + out abound horrendously. This is especially true of chars where + some compilers occassionally extract the wrong byte from the + promoted int in the recieving function. + + -- Be careful passing floats to functions as some compilers promote + floats to doubles when passing them as an argument. This can + cause spurious warnings and and strange side effects. + + -- Explicitly cast assignments and expressions as needed, and + carefully watch that you really don't need to make those + identifiers of that type originally. While the promotion order + is constant across implementations, the size of the types + aren't. This can cause difficult side effects. + + If your code needs a lot of casts to get past Lint, then you + probably need to rethink some of your approaches. + + -- Take care to cast all #defined constants if in doubt. For large + values (longs), always cast as longs, or place an 'L' at the end + of the constant. Some compilers handle this area erraticly if + left up to them. + + -- Never ever rely on order of evaluation of function parameters. + This can occur when listing a funtion call as a parameter to + another funtion, or as an unintentional side effect from passing + assignments or function calls as parameters. + + char *pc_modify (char *); + + printf ("This string [%s] becomes [%s]\n", + pc_string, pc_modify (pc_string)); /* Bad code */ + + -- Do not use NULL for anything but pointers. Do not use NULL for + string terminations: use the ASCII constant NUL, '\0', or a + #defined type which equates to that. + + -- Never EVER pass a #defined macro an incremented or decremented + value (++,or --) or an assignment as a parameter. This is + because many #defined macros may reference their arguments + multiple times. This is especially true of the macros #defined + in ctype.h. + + eg. + + #define iscsymf(c) (isalpha(c) || ((c) == '_')) + + If called as so: + + iscsym(var++); + + it will be expanded by the preprocessor to: + + (isalpha(var++) || ((var++) == '_')) + + with var being incremented twice. + + -- Avoid passing any functions incremented or decremented values + ("++" or "--"), or assignments. Some standard and commercial + library calls are actually #defined macros. This type of + "error" can lead to order of evaluation problems as different + compilers process function arguments in different orders. + + -- Explicitly initialise pointers. Do not rely on calloc(), + memset() or other such functions to initialise pointers. + Initialise them explicitly. + +"K&R" as mentioned above refers to "The C Programming Language" +written by Brian W Kernighan & Dennis M Ritchie. + +"PC-Lint" is a commercial version of Lint for the PC, as sold by +Gimpel Software. PC-Lint is generally acknowledged as the tightest +and most discerning Lint on any platform. + +There are several books which cover the areas of portable code which +may also help: + + "C Programming Guidelines" + by Thomas Plum + pub. by Plum Hall + ISBN 0-911537-03-1 + + "Portability and the C Language" + by Rex Jaeschke + pub. by Hayden Books + ISBN 0-672-48428-5 + + "Portable C Software" + by Mark R. Horton + pub. by Prentice Hall + ISBN 0-13-868050-7 + + "Portable C" + by Henry Rabinowitz & Chaim Schaap + pub. by Prentice Hall + ISBN 0-13-685967-4 + + "Portable C and Unix System Programming" + by J.E. Lapin + pub. Prentice-Hall + ISBN 0-13-686494-5 + +[END] diff --git a/reference/C/CONTRIB/SNIP/c_prec.txt b/reference/C/CONTRIB/SNIP/c_prec.txt new file mode 100755 index 0000000..1751853 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/c_prec.txt @@ -0,0 +1,74 @@ + Operator Precedence and Associativity Rules in C / C++ + ============================================================================ + :: scope resolution (C++, e.g. name::member) left-to-right + :: global (C++, e.g. ::name) + ---------------------------------------------------------------------------- + ( ) function call left-to-right + [ ] array element + . class, structure or union member + -> pointer reference to member + :: scope access / resolution (C++) + sizeof size of object in bytes + sizeof size of type in bytes + ---------------------------------------------------------------------------- + ++ post increment (lvalue++) right-to-left + ++ pre increment (++lvalue) + -- post decrement (lvalue--) + -- pre decrement (--lvalue) + ~ bitwise complement + ! logical not + - unary minus + + unary plus + & address of + * contents of + new create object (C++) + delete destroy object (C++) + delete[] destroy array (C++) + (type) cast to type + ---------------------------------------------------------------------------- + .* member pointer (C++) left-to-right + ->* pointer reference to member pointer (C++) + ---------------------------------------------------------------------------- + * multiply left-to-right + / divide + % remainder + ---------------------------------------------------------------------------- + + add left-to-right + - subtract + ---------------------------------------------------------------------------- + << bitwise left shift left-to-right + >> bitwise right shift + ---------------------------------------------------------------------------- + < scalar less than left-to-right + <= scalar less than or equal to + > scalar greater than + >= scalar greater than or equal to + ---------------------------------------------------------------------------- + == scalar equal left-to-right + != scalar not equal + ---------------------------------------------------------------------------- + & bitwise and left-to-right + ---------------------------------------------------------------------------- + ^ bitwise exclusive or left-to-right + ---------------------------------------------------------------------------- + | bitwise or left-to-right + ---------------------------------------------------------------------------- + && logical and left-to-right + ---------------------------------------------------------------------------- + || logical inclusive or left-to-right + ---------------------------------------------------------------------------- + ? : conditional expression right-to-left + ---------------------------------------------------------------------------- + = assignment operator right-to-left + also += -= *= /= %= + &= ^= |= >>= <<= + ---------------------------------------------------------------------------- + , sequential expression left-to-right + ---------------------------------------------------------------------------- + +All of the operators in this table can be overloaded (C++) except: + + . C++ direct component selector + .* C++ dereference + :: C++ scope access/resolution + ?: Conditional diff --git a/reference/C/CONTRIB/SNIP/cal.c b/reference/C/CONTRIB/SNIP/cal.c new file mode 100755 index 0000000..f564093 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/cal.c @@ -0,0 +1,144 @@ +/* +** CAL - a calendar for DOS +** +** a public domain demo using Ray Gardner's SCALDATE.C scalar date functions +** by Bob Stout +*/ + +#include +#include + +/* +** function prototypes for SCALDATE.C +*/ + +int isleap (unsigned); +long ymd_to_scalar (unsigned, unsigned, unsigned); + +/* +** calendar generation information +*/ + +int days[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; +char *month[12] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; +char *daynames[8] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"}; + +/* +** box drawing stuff +*/ + +#ifdef MSDOS + const char *topborder = "\xd5\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" + "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" + "\xcd\xcd\xcd\xcd\xb8"; + const char *midborder = "\xc6\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" + "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" + "\xcd\xcd\xcd\xcd\xb5"; + const char *botborder = "\xd4\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" + "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" + "\xcd\xcd\xcd\xcd\xbe"; + const char *line = "\xb3"; +#else + const char *line = ""; +#endif + +/* +** tell 'em they messed up +*/ + +void usage(void) +{ + puts("Usage: CAL m y"); + puts("where: m = month (1 - 12)"); + puts(" y = year (1 - 99, 1800 - 3000)"); + exit(-1); +} + +/* +** Define ISO to be 1 for ISO (Mon-Sun) calendars +*/ + +#ifndef ISO + #define ISO 0 +#endif + +#if (ISO != 0 && ISO != 1) + #error ISO must be set to either 0 or 1 +#endif + +/* +** here's where the real work's done +*/ + +int main(int argc, char *argv[]) +{ + int day, day_1, numdays, i, j; + unsigned yr, mo; + + if (3 > argc) + usage(); + + yr = atoi(argv[2]); + mo = atoi(argv[1]); + + if (!mo || 12 < mo) + usage(); + + if (100 > yr) + yr += 1900; + + if (3000 < yr || 1800 > yr) + usage(); + + for (i = 0, mo -= 1; i < 3; ++i, ++mo) + { + if (!mo) + { + mo = 12; + --yr; + } + if (12 < mo) + { + mo = 1; + ++yr; + } + numdays = days[mo - 1]; + if (2 == mo && isleap(yr)) + ++numdays; + day_1 = (int)((ymd_to_scalar(yr, mo, 1) - (long)ISO) % 7L); + +#ifdef MSDOS + if (!i) + puts(topborder); +#endif + fputs(line, stdout); + for (j = 0; j < 7; ) + { + fputs(daynames[ISO + j], stdout); + if (7 != ++j) + fputc(' ', stdout); + } + printf("%s < %s, %d\n%s", line, month[mo - 1], yr, line); + + for (day = 0; day < day_1; ++day) + fputs(" ", stdout); + for (day = 1; day <= numdays; ++day, ++day_1, day_1 %= 7) + { + if (!day_1 && 1 != day) + printf("\b%s\n%s", line, line); + printf("%3d ", day); + } + for ( ; day_1; ++day_1, day_1 %= 7) + fputs(" ", stdout); +#ifdef MSDOS + printf("\b%s\n", line); + if (2 > i) + puts(midborder); + else puts(botborder); +#else + fputc('\n', stdout); +#endif + } + return 0; +} diff --git a/reference/C/CONTRIB/SNIP/calsupp.c b/reference/C/CONTRIB/SNIP/calsupp.c new file mode 100755 index 0000000..113f08a --- /dev/null +++ b/reference/C/CONTRIB/SNIP/calsupp.c @@ -0,0 +1,65 @@ +/* calsupp.c -- public domain by Ray McVay */ + +/* This module provides three handy date related functions: +** dow() - Returns the day of the week for a given date +** IsLeap() - Returns 1 if a year is a leap year +** GetToday() - Returns today's date from the operating system +*/ + +#include + +/* +** Returns an integer that represents the day of the week for +** the date passed as parameters. +** +** day: day of month +** mon: month (1-12) +** yr: year +** +** returns 0-6 where 0 == sunday +*/ + +int dow(int day, int mon, int yr) +{ + int dow; + + if (mon <= 2) + { + mon += 12; + yr -= 1; + } + dow = (day + mon * 2 + ((mon + 1) * 6) / 10 + + yr + yr / 4 - yr / 100 + yr / 400 + 2); + dow = dow % 7; + return ((dow ? dow : 7) - 1); +} + + +/* +** Returns 1 if yr is a leap year, 0 if it is not +*/ + +int IsLeap(int yr) +{ + if (yr % 400 == 0) return 1; + if (yr % 100 == 0) return 0; + if (yr % 4 == 0) return 1; + else return 0; +} + + +/* +** Returns the current day, month and year in the referenced variables +*/ + +void GetToday(int *day, int *mon, int *yr) +{ + struct tm today; + time_t ctime; + + time(&ctime); + today = *localtime(&ctime); + *day = today.tm_mday; + *mon = today.tm_mon + 1; + *yr = today.tm_year + 1900; +} diff --git a/reference/C/CONTRIB/SNIP/cant.c b/reference/C/CONTRIB/SNIP/cant.c new file mode 100755 index 0000000..bb559e6 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/cant.c @@ -0,0 +1,22 @@ +/* +** CANT.C - An fopen() replacement with error trapping +** +** public domain by Bob Stout +** +** Call just as you would fopen(), but make sure your exit functions are +** registered with atexit(). +*/ + +#include + +FILE *cant(char *fname, char *fmode) +{ + FILE *fp; + + if (NULL == (fp = fopen(fname, mode))) + { + fprintf(stderr, "Can't open %s\n", fname); + exit(EXIT_FAILURE); + } + return fp; +} diff --git a/reference/C/CONTRIB/SNIP/cast.h b/reference/C/CONTRIB/SNIP/cast.h new file mode 100755 index 0000000..49f7668 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/cast.h @@ -0,0 +1,23 @@ +/* +** public domain demo by Bob Stout +*/ + +#define CAST(new_type,old_object) (*((new_type *)&old_object)) + +#if 0 +************************************************************************* +* * +* /* Example of CAST macro at work */ * +* * +* union { * +* char ch[4]; * +* int i[2]; * +* } my_union; * +* * +* long longvar; * +* * +* longvar = (long)my_union; /* Illegal cast */ * +* longvar = CAST(long, my_union); /* Legal cast */ * +* * +************************************************************************* +#endif /* 0 */ diff --git a/reference/C/CONTRIB/SNIP/cbtrap.asm b/reference/C/CONTRIB/SNIP/cbtrap.asm new file mode 100755 index 0000000..1a9662e --- /dev/null +++ b/reference/C/CONTRIB/SNIP/cbtrap.asm @@ -0,0 +1,63 @@ + PAGE ,132 + +; Install a custom Interrupt 1b (Ctrl-Break exception) handler +; +; Public domain by Bob Stout +; +; Requires MASM 5.1 or later or equivalent +; +; Assemble with: MASM /Mx /z ... +; TASM /jMASM /mx /z ... + +% .MODEL memodel,C ;Add model support via command + ;line macros, e.g. + ;MASM /Dmemodel=LARGE + + .DATA? +_origvec dd ? + + .DATA + + public cbrcvd + +cbrcvd dw 0 + + .CODE + +; +; This is our actual ISR +; +myint1b: + mov ax,-1 + mov cbrcvd,ax + iret + +; +; Call this to install our ISR +; +ins1b PROC USES AX BX DS ES + mov ax,351bh ;get old vector... + int 21h + mov word PTR _origvec,bx + mov word PTR _origvec+2,es ;...and save it + + push cs ;get myint1b segment in DS + pop ds + mov dx, OFFSET myint1b ;install myint1b in int 1bh + mov ax,251bh + int 21h + ret +ins1b ENDP + +; +; Call this to uninstall our ISR +; +redo1b PROC USES AX BX DS + mov dx, word PTR _origvec ;restore original vector + mov ds, word PTR _origvec+2 + mov ax,251bh + int 21h + ret +redo1b ENDP + + end diff --git a/reference/C/CONTRIB/SNIP/ccomcall.c b/reference/C/CONTRIB/SNIP/ccomcall.c new file mode 100755 index 0000000..290e086 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/ccomcall.c @@ -0,0 +1,36 @@ +/* +** Call undocumented Int 2Eh to invoke COMMAND.COM +** +** demo by Bob Stout +** +** NOTES: Dangerous code - will abort batch files in progress and +** occasionally have other undesirable effects. +** +** Requires INT2E.ASM +*/ + +#include +#include + +extern void _Int_2E(char *); + +void C_Com_Call(char *string) +{ + char *buf; + + buf = (char *)malloc(strlen(string) + 3); + strcat(strcpy(&buf[1], string), "\r"); + buf[0] = (char)strlen(&buf[1]); + _Int_2E(buf); + free(buf); +} + +#ifdef TEST + +void main(int argc, char *argv[]) +{ + C_Com_Call(argv[1]); +} + +#endif + diff --git a/reference/C/CONTRIB/SNIP/cctrap.asm b/reference/C/CONTRIB/SNIP/cctrap.asm new file mode 100755 index 0000000..a6b6d5a --- /dev/null +++ b/reference/C/CONTRIB/SNIP/cctrap.asm @@ -0,0 +1,64 @@ + PAGE ,132 + +; Install a custom Interrupt 23 (Ctrl-C exception) handler +; +; Public domain by Bob Stout +; +; Requires MASM 5.1 or later or equivalent +; +; Assemble with: MASM /Mx /z ... +; TASM /jMASM /mx /z ... + + +% .MODEL memodel,C ;Add model support via command + ;line macros, e.g. + ;MASM /Dmemodel=LARGE + + .DATA? +_origvec dd ? +_newvec dd ? + + .CODE + +; +; This is our actual ISR +; + +myint23: + call dword PTR _newvec ;call our handler + iret + +; +; Call this to install our ISR +; + +ins23 PROC USES AX BX DS ES, offs:WORD, segm:WORD + mov ax,3523h ;get old vector... + int 21h + mov word PTR _origvec,bx + mov word PTR _origvec+2,es ;...and save it + mov ax,offs ;load handler offset... + mov word PTR _newvec,ax + mov ax,segm ; & segment into _newvec + mov word PTR _newvec+2,ax + push cs ;get myint23 segment in DS + pop ds + mov dx, OFFSET myint23 ;install myint23 in int 23h + mov ax,2523h + int 21h + ret +ins23 ENDP + +; +; Call this to uninstall our ISR +; + +redo23 PROC USES AX BX DS + mov dx, word PTR _origvec ;restore original vector + mov ds, word PTR _origvec+2 + mov ax,2523h + int 21h + ret +redo23 ENDP + + end diff --git a/reference/C/CONTRIB/SNIP/cdir.c b/reference/C/CONTRIB/SNIP/cdir.c new file mode 100755 index 0000000..853cecb --- /dev/null +++ b/reference/C/CONTRIB/SNIP/cdir.c @@ -0,0 +1,127 @@ +/* +** CDIR.C +** +** Written By: Lynn R. Lively +** Date Written: 9/18/91 +** +** Purpose: To provide a change directory facility that will cross +** drive/partition boundries. Never did understand why +** MSDOS cd wouldn't do this already. +** +**----------------------------------------------------------------- +** I hereby place this work into the Public Domain. It may be used +** for any legal purpose public or private. Use this material at +** your own risk. I accept no responsibility for the accuracy or +** usability of the information contained herein. Neither do I +** accept liability for any possible damage caused by use of this +** material. However, should you have a problem, question, or +** suggestion I would be glad to help in any way that I can. You +** can reach me at (H) 713-893-7875 or (W) 713-591-6611 x 149. +**----------------------------------------------------------------- +*/ + +/* +** Change History +** +** Rev # Date By Description of change +** 1.00 | 09/18/91 | LRL | Original Version +** 1.01 | 09/18/91 | RBS | Added MSC, ZTC support for SNIPPETS +**----------------------------------------------------------------- +** Directory of initials: +** Initials Name +** LRL Lynn R. Lively +** RBS Bob Stout +*/ + + +#include +#include + +#ifdef __TURBOC__ + #include +#else + #include + #include + + #ifdef __ZTC__ + #define _dos_getdrive(d) dos_getdrive(d) + #define _dos_setdrive(d,m) dos_setdrive(d,m) + #define drive_t unsigned + #else + #define drive_t int + #endif + + drive_t getdisk(void) + { + drive_t drive; + + _dos_getdrive(&drive); + return drive - 1; + } + + drive_t setdisk(drive_t drive) + { + drive_t max_drives; + + _dos_setdrive(drive + 1, &max_drives); + return max_drives - 1; + } +#endif + +main (int argc, char * argv[]) +{ + int d; + int max_d; + + char wk_str[128]; + + if (argc > 1) + { + strupr (argv[1]); + if (argv[1][1] == ':') + { + /* + ** Find out what the maximum drive number can be. + */ + + max_d = getdisk (); + max_d = setdisk (max_d); + + d = argv[1][0] - 'A'; + if (d < max_d) + { + /* + ** If the drive specification was valid position to it + ** and then do a change directory. + */ + + setdisk (d); + chdir (argv[1]); + } + else + { + puts ("Invalid drive specification"); + return -1; + } + } + else + { + /* + ** If the argument has no drive spec just do a regular + ** change directory. + */ + + chdir (argv[1]); + } + } + else + { + /* + ** If no arguments are passed, return the current working + ** directory path just like MSDOS cd does. + */ + + puts (getcwd (wk_str, sizeof (wk_str))); + } + return 0; +} diff --git a/reference/C/CONTRIB/SNIP/center.c b/reference/C/CONTRIB/SNIP/center.c new file mode 100755 index 0000000..f078a52 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/center.c @@ -0,0 +1,49 @@ +/* public domain by Jerry Coffin. Tested with MSC 7.0 */ +/* written primarily for clarity, not speed... */ +/* requires w_wrap.c and w_wrap.h from snippets. */ + + +#include +#include +#include +#include "w_wrap.h" + +void center(FILE *file, char *string, size_t width) +{ + char *line,*end_line; + size_t spaces; + int last = 0; + size_t len; + + word_wrap(string,width); + line = string; + while (!last) + { + end_line = strchr(line,'\n'); + if (NULL==end_line) + { + last = 1; + end_line = strchr(line,'\0'); + } + len = end_line - line; + spaces = (width - len) / 2 ; + fprintf(file,"\n%*c%*.*s",spaces,' ',len,len,line); + line = end_line + 1; + } +} + +#ifdef TEST + +int main(void) +{ + char *string = "This is a long string to see if it will be" + " printed out correctly but I'm not sure whether it will work" + " correctly or not. I guess we'll see when we try it out."; + + printf("\nHere's the string centered in 50 columns.\n"); + center(stdout,string,50); + printf("\n\nAnd here it's centered in 72 columns.\n"); + center(stdout,string,72); +} + +#endif diff --git a/reference/C/CONTRIB/SNIP/cerrinst.asm b/reference/C/CONTRIB/SNIP/cerrinst.asm new file mode 100755 index 0000000..385ccd2 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/cerrinst.asm @@ -0,0 +1,100 @@ + PAGE ,132 + +; Install an Interrupt 24 (DOS critical error exception) handler +; +; Public domain by Bob Stout +; +; Requires MASM 5.1 or later or equivalent +; +; Assemble with: MASM /Mx /z ... +; TASM /jMASM /mx /z ... + +% .MODEL memodel,C ;Add model support via command + ;line macros, e.g. + ;MASM /Dmemodel=LARGE + + .DATA? + + PUBLIC cedevdvr, cetype, ceerror, cereturn +_origvec dd ? +_newvec dd ? +cedevdvr dd ? +cetype dw ? +ceerror dw ? +cereturn db ? + + .CODE + +; +; This is our actual ISR +; +myint24: + push ds ;save registers which may be + push es ;required in case "Retry" is + push bx ;selected + push cx + push dx + push si + push di + push bp + mov word PTR cedevdvr,si ;save device driver header address + mov word PTR cedevdvr+2,bp + mov cetype,ax ;save error type information + mov ceerror,di ;save error code information + call far PTR _newvec ;call our handler + mov al,cereturn ;set up return code (abort, retry...) + pop bp ;restore necessary registers + pop di + pop si + pop dx + pop cx + pop bx + pop es + pop ds + iret + +; +; Call this to install our ISR +; +; void (_far *)() ins24(unsigned short segm, unsigned short offs); +; void (_far *)() ins24((void _far *handler)()); +; +; Paramters (option 1) - 1 : Segment of handler +; 2 : Offset of handler +; +; Paramters (option 2) - 1 : Address of handler +; +; Returns pointer to old handler +; +ins24 PROC USES AX BX DS ES, segm:WORD, offs:WORD + mov ax,3524h ;get old vector... + int 21h + mov word PTR _origvec,bx + mov word PTR _origvec+2,es ;...and save it + mov ax,offs ;load handler offset... + mov word PTR _newvec,ax + mov ax,segm ; & segment into _newvec + mov word PTR _newvec+2,ax + push cs ;get myint24 segment in DS + pop ds + mov dx, OFFSET myint24 ;install myint24 in int 24h + mov ax,2524h ; into Interrupt 24h + int 21h + mov ax,word PTR _origvec + mov dx,word PTR _origvec+2 +ins24 ENDP + +; +; Call this to uninstall our ISR +; +; void redo24(void); +; +redo24 PROC USES AX BX DS + mov dx, word PTR _origvec ;restore original vector + mov ds, word PTR _origvec+2 + mov ax,2524h + int 21h + ret +redo24 ENDP + + end diff --git a/reference/C/CONTRIB/SNIP/cerrtrap.asm b/reference/C/CONTRIB/SNIP/cerrtrap.asm new file mode 100755 index 0000000..9d1eab9 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/cerrtrap.asm @@ -0,0 +1,134 @@ + PAGE ,132 + +; A sample Interrupt 24 (DOS critical error exception) handler +; +; Public domain by Bob Stout +; +; Requires MASM 5.1 or later or equivalent +; +; Assemble with: MASM /Mx /z ... +; TASM /jMASM /mx /z ... + +% .MODEL memodel,C ;Add model support via command + ;line macros, e.g. + ;MASM /Dmemodel=LARGE + + EXTRN cedevdvr:dword, cetype:word, ceerror:word, cereturn:byte + EXTRN read_err:far, write_err:far, term_err:far + EXTRN no_paper:far, fixup_ret:far, FAT_err:far + + ;NOTE: All the above routines MUST set cereturn to: + ; 0 - Ignore + ; 1 - Retry + ; 2 - Abort + ; 3 - Fail (DOS 3.3 and later) + + .DATA? + + PUBLIC osver, rmvbl, exerr, locus, class, suggest +osver db ? +rmvbl db ? +exerr dw ? +locus db ? +class db ? +suggest db ? + + .CODE + +; +; This is called by myint24 +; +; extern int (*read_err)(), +; (*write_err)(), +; (*term_err)(), +; (*no_paper)(), +; (*fixup_ret)(), +; (*FAT_err)(); +; +; Each returns: 0 - Ignore +; 1 - Retry +; 2 - Abort +; 3 - Fail (DOS 3.3 and later) +; +mynew24 PROC USES BX + mov ah,030h ;get DOS version number + int 21 + or al,al ;zero means DOS 1.x + jnz NotDOS1 + mov al,1 +NotDOS1: + mov osver,al ;save DOS version + mov ax,cetype ;get type of exception... + mov bx,ax ; & save it for later + and ax,80h ;disk error? + jnz NotDiskErr ;no, continue + cmp al,1 ;yes, DOS 1.x? + jz wrong_DOS ;yes, can't check for removable media + mov ah,-1 ;no, assume removable media + test word PTR cedevdvr,0800h ;is the media removable? + jz removable + xor ah,ah ;no, flag fixed media +removable: + mov rmvbl,ah ;save media type + cmp al,3 ;DOS 3.0 or greater? + jb wrong_DOS ;no, skip it + push bx ;yes, save cetype info... + push ds ; & other regs + push es + push dx + push si + push di + push bp + mov ah,59h ;get extended error info + int 21 + pop bp ;restore regs + pop di + pop si + pop dx + pop es + pop ds + mov exerr,ax ;save extended error code... + mov locus,ch ; locus... + mov class,bh ; class... + mov suggest,bl ; & suggested action + pop bx ;restore cetype info +wrong_DOS: + mov ax,bx ;get exception type + and ax,06h ;FAT problems? + cmp ax,02h + jnz ok_fat ;no, continue + jmp far PTR FAT_err ;yes, handle it +ok_fat: + mov ax,bx ;get exception type + and ax,01h ;handle read and write separately + jz rd_err + jmp far PTR write_err +rd_err: + jmp far PTR read_err +NotDiskErr: + test ceerror,0009h ;printer out of paper? + jnz not_eop ;no, continue + jmp far PTR no_paper ;yes, handle it +not_eop: + test word PTR cedevdvr,8000h ;character device? + jnz unknown ;no, continue + jmp far PTR term_err ;yes, assume bad terminal I/O + +; +; If we get here, we haven't identified the error. We now call fixup_ret() +; to resolve which action to take. This will usually involve the information +; in exerr qualified by the version of DOS in use and is best left to coding +; in a higher level language like C. +; +; NOTE: It is IMPERATIVE that the return value of fixup_ret() default to 2 +; to insure that if all else fails, the critcal error handler aborts! +; + +unknown: + call far PTR fixup_ret ;unknown error - handle loose ends... + xor ah,ah ; & return + mov cereturn,al + ret +mynew24 ENDP + + end diff --git a/reference/C/CONTRIB/SNIP/changprn.c b/reference/C/CONTRIB/SNIP/changprn.c new file mode 100755 index 0000000..e848342 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/changprn.c @@ -0,0 +1,52 @@ +/* +** change_prn() +** +** A function to change the standard printer device for the duration +** of a program. Valid new device codes are: +** +** 0 - LPT1 +** 1 - LPT2 +** 2 - LPT3 +** 3 - COM1 +** 4 - COM2 +** 5 - CON +** +** Original Copyright 1988-1991 by Bob Stout as part of +** the MicroFirm Function Library (MFL) +** +** This subset version is functionally identical to the +** version originally published by the author in Tech Specialist +** magazine and is hereby donated to the public domain. +*/ + +#include + +int change_prn(int device) +{ + char *newdev; + + switch (device) + { + case 0: + newdev = "LPT1"; + break; + case 1: + newdev = "LPT2"; + break; + case 2: + newdev = "LPT3"; + break; + case 3: + newdev = "COM1"; + break; + case 4: + newdev = "COM2"; + break; + case 5: + newdev = "CON"; + break; + default: + return -1; + } + return (NULL == freopen(newdev, "w", stdprn)); +} diff --git a/reference/C/CONTRIB/SNIP/chbytes.c b/reference/C/CONTRIB/SNIP/chbytes.c new file mode 100755 index 0000000..b1c21f2 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/chbytes.c @@ -0,0 +1,203 @@ +/* +** CHBYTES.C - Change bytes in a file +** +** This program searches a file for a sequence of bytes. If they are +** found, they are replaced with zeros. It was originally developed for +** a friend who needed a program to call from Paradox to remove printer +** control sequences from formatted print files. The requirements were +** 1) since it is called by another program, all status has to be returned +** in the errorlevel with no screen messages allowed, and 2) The file must +** remain the same length, so the deleted sequences must only be replaced +** with ASCII NULs. +** +** Syntax: CHBYTES filename pattern_1 [pattern_2 [...pattern_N]] +** where: Each pattern is a comma-separated list of bytes, each of which +** may be of the following forms: +** C - Any single character will be treated as literal. +** XXh - "XX" will be interpreted as a hexidecimal number (both +** 1- and 2-digit hex numbers are allowed). +** NNNd - "NNN" will be interpreted as a decimal number (both +** 1-, 2-, and 3-digit decimal numbers are allowed). +** +** e.g. CHBYTES printer.fil 12d 1bh,[,3,x +** would zero out form feeds and the escape sequence "[3x" +** +** Returns: 0 - Success +** 1 - No filename +** 2 - No arguments +** 3 - Error opening file +** 4 - Not enough memory +** 5 - Bad argument +** 6 - Error reading file +** 7 - Error writing file +** +** Public domain by Bob Stout +*/ + +#include +#include +#include +#include + +#ifdef __ZTC__ + int _okbigbuf = 0; +#endif + +#define LAST_CHAR(s) (((char *)(s))[strlen((char *)(s)) - 1]) + +#ifndef max + #define max(x,y) (((x) >= (y)) ? (x) : (y)) +#endif + +typedef enum {ERROR = -1, SUCCESS, FALSE = 0, TRUE} LOGICAL; + +int bufsize; + +struct { + char pattern[40]; /* pattern to find */ + int numbytes; /* length of pattern */ +} search[40]; + +int main (int argc, char *argv[]) +{ + FILE *fp = NULL; + char *buf = NULL, *getbuf(void); + fpos_t rpos; + int i, patterns, max_bytes = 0; + LOGICAL hex2char(const char *, char *); + + if (2 > argc) /* no filename */ + return 1; + if (3 > argc) /* no argument */ + return 2; + if (NULL == (fp = fopen(argv[1], "r+b"))) + return 3; /* file open error */ + if (NULL == (buf = getbuf())) + return 4; /* no memory for buffer */ + + patterns = argc - 2; /* process arguments */ + for (i = 2; i < argc; ++i) + { + char *p, *ptr; + + if (NULL != (ptr = strtok(argv[i], ","))) + { + p = search[i - 2].pattern; + do + { + search[i - 2].numbytes++; + if (1 == strlen(ptr)) + { + *p++ = *ptr; + continue; + } + switch (toupper(LAST_CHAR(ptr))) + { + case 'D': + LAST_CHAR(ptr) = '\0'; + *p++ = (char)atoi(ptr); + break; + case 'H': + LAST_CHAR(ptr) = '\0'; + if (ERROR == hex2char(ptr, p++)) + return 5; + break; + default: + return 5; + } + } while (NULL != (ptr = strtok(NULL, ","))); + *p = '\0'; + max_bytes = max(max_bytes, search[i - 2].numbytes); + } + else return 5; + } + + fgetpos(fp, &rpos); /* save where we are */ + while (1) + { + int bytes, n; + LOGICAL modified; + + if (max_bytes > (bytes = (int)fread(buf, 1, bufsize, fp))) + { + if (0 == bytes && !feof(fp)) + return 6; /* something's wrong! */ + else break; /* all done! */ + } + for (n = 0, modified = FALSE; n < patterns; ++n) + { + /* check each pattern in turn */ + + for (i = 0; i < (bytes - max_bytes + 1); ++i) + { + int j; + + if (buf[i] != *(search[n].pattern)) + continue; + if (SUCCESS != strncmp(&buf[i], + search[n].pattern, search[n].numbytes)) + { + continue; + } + + /* found one! replace it in the buffer */ + + for (j = 0; j < search[n].numbytes; ++j, ++i) + buf[i] = '\0'; + modified = TRUE; + } + } + if (modified) /* write changes, if any*/ + { + fpos_t wpos = rpos; + + fsetpos(fp, &wpos); + if (bytes != (int)fwrite(buf, 1, bytes, fp)) + return 7; + fsetpos(fp, &rpos); + } + rpos += bytes - max_bytes + 1; /* get another buffer */ + fsetpos(fp, &rpos); + } + fclose(fp); + return SUCCESS; +} + +/* +** Allocate the largest buffer we can +*/ + +char *getbuf(void) +{ + register char *buffer; + + for (bufsize = 0x4000; bufsize >= 128; bufsize >>= 1) + { + if (NULL != (buffer = (char *) malloc(bufsize))) + return buffer; + } + return NULL; +} + +/* +** Convert ASCII hex char to char +*/ + +#define xdigit(c) (toupper(c) - (((c) > '9') ? 'A' - 10 : '0')) + +LOGICAL hex2char(const char *hex, char *buf) +{ + int ch = 0; + char *p = (char *)hex; + + while(*p) + { + if (!isxdigit(*p)) + return ERROR; + ch <<= 4; + ch += xdigit(*p); + ++p; + } + *buf = (char)ch; + return SUCCESS; +} diff --git a/reference/C/CONTRIB/SNIP/checkexe.c b/reference/C/CONTRIB/SNIP/checkexe.c new file mode 100755 index 0000000..8ea43cb --- /dev/null +++ b/reference/C/CONTRIB/SNIP/checkexe.c @@ -0,0 +1,126 @@ +/* +** CHECKEXE.C - checksum protection for executable files +** +** by: Bob Jarvis +*/ + +#include +#include +#include +#include + +static struct { + unsigned char marker[16]; + unsigned long checksum; +} marker_struct = {"CHECKEXE MARKER",0L}; + +void checkexe(char *fname) +{ + FILE *fptr; + unsigned int c; + int first_time = 0, i; + char buffer[14]; + unsigned long chksum = 0L; + unsigned long l; + unsigned long marker_offset; + unsigned char *charptr; + time_t tm; + + fptr = fopen(fname,"r+b"); + if(fptr == NULL) + { + fprintf(stderr,"checkexe : unable to open input file '%s'\n", + fname); + exit(99); + } + + setvbuf(fptr, NULL, _IOFBF, 32767); /* try to get a 32K buffer */ + + /* + * If this is the first time the check has been run, scan the entire file + * to find the marker. Otherwise proceed. + */ + + if(marker_struct.checksum == 0L) + { + first_time = 1; + + c = fgetc(fptr); + while(!feof(fptr)) + { + if(c == (unsigned int)marker_struct.marker[0]) + { + fread(buffer,sizeof(buffer),1,fptr); + if(memcmp(buffer,&marker_struct.marker[1], + sizeof(buffer)) == 0) + { + marker_offset = ftell(fptr) + 1L; + break; + } + fseek(fptr,-13L,SEEK_CUR); + } + + c = fgetc(fptr); + } + + if(feof(fptr)) + { + fprintf(stderr,"checkexe : unable to locate marker\n"); + exit(99); + } + + /* Change the marker field to random values */ + + tm = time(NULL); + + srand((unsigned int)tm); + + for(i = 0 ; i < sizeof(marker_struct.marker) ; ++i) + marker_struct.marker[i] = (unsigned char) rand(); + + fseek(fptr,marker_offset - sizeof(marker_struct.marker),SEEK_SET); + + fwrite(marker_struct.marker,sizeof(marker_struct.marker),1,fptr); + } + + /* Calculate the checksum for the entire file */ + + rewind(fptr); + + c = fgetc(fptr); + for(l = 0 ; !feof(fptr) ; ++l) + { + chksum += (unsigned long)c; + c = fgetc(fptr); + } + + if(first_time) + { + marker_struct.checksum = chksum; + fseek(fptr,marker_offset,SEEK_SET); + fwrite(&marker_struct.checksum,sizeof(unsigned long),1,fptr); + } + else + { + charptr = (unsigned char*) &marker_struct.checksum; + + for(i = 0 ; i < sizeof(marker_struct.checksum) ; ++i) + chksum -= (unsigned long)(charptr[i]); + + if(chksum != marker_struct.checksum) + { + fprintf(stderr, "\acheckexe : %s has been altered, " + "possibly by a virus\n", fname); + exit(99); + } + } + + fclose(fptr); + return; +} + +main(int argc, char *argv[]) +{ + checkexe(argv[0]); + return EXIT_SUCCESS; +} diff --git a/reference/C/CONTRIB/SNIP/checksum.c b/reference/C/CONTRIB/SNIP/checksum.c new file mode 100755 index 0000000..4071f02 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/checksum.c @@ -0,0 +1,39 @@ +/* +** CHECKSUM.C - Compute the checksum of a file +** +** public somain demo by Bob Stout +*/ + +#include + +unsigned checksum(void *buffer, size_t len, unsigned int seed) +{ + unsigned char *buf = (unsigned char *)buffer; + size_t i; + + for (i = 0; i < len; ++i) + seed += (unsigned int)(*buf++); + return seed; +} + +#ifdef TEST + +#include + +main() +{ + FILE *fp; + size_t len; + char buf[4096], *file = "CHECKSUM.C"; + + if (NULL == (fp = fopen(file, "rb"))) + { + printf("Unable to open %s for reading\n", file); + return -1; + } + len = fread(buf, sizeof(char), sizeof(buf), fp); + printf("%d bytes read\n", len); + printf("The checksum of %s is %#x\n", file, checksum(buf, len, 0)); +} + +#endif diff --git a/reference/C/CONTRIB/SNIP/chgext.c b/reference/C/CONTRIB/SNIP/chgext.c new file mode 100755 index 0000000..b394572 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/chgext.c @@ -0,0 +1,71 @@ +/* +** chgext.c - Change a file's extension +** +** public domain by Bob Stout +** +** Arguments: 1 - Pathname +** 2 - Old extension (NULL if don't care) +** 3 - New extension +** +** Returns: Pathname or NULL if failed +** +** Note: Pathname buffer must be long enough to append new extension +** +** Side effect: Converts Unix style pathnames to DOS style +*/ + +#include +#include + +char *chgext(char *path, char *oldext, char *newext) +{ + char *p; + + /* Convert to DOS-style path name */ + + for (p = path; *p; ++p) + if ('/' == *p) + *p = '\\'; + + /* Find extension or point to end for appending */ + + if (NULL == (p = strrchr(path, '.')) || NULL != strchr(p, '\\')) + p = strcpy(&path[strlen(path)], "."); + ++p; + + /* Check for old extension */ + + if (oldext && strcmp(p, oldext)) + return NULL; + + /* Add new extension */ + + while ('.' == *newext) + ++newext; + strncpy(p, newext, 3); + return path; +} + +#ifdef TEST + +void main(int argc, char *argv[]) +{ + char *retval, *old_ext = NULL, path[128]; + + if (2 > argc) + { + puts("Usage: CHGEXT path [old_ext]"); + puts("\nChanges extension to \".TST\""); + puts("Old extension optional"); + return; + } + strcpy(path, strupr(argv[1])); + if (2 < argc) + old_ext = strupr(argv[2]); + if (NULL == (retval = chgext(path, old_ext, ".TSTstuff"))) + puts("chgext() failed"); + else printf("chgext(%s, %s, TST)\n...returned...\n%s\n", argv[1], + old_ext ? old_ext : "NULL", path); +} + +#endif /* TEST */ diff --git a/reference/C/CONTRIB/SNIP/chmod.c b/reference/C/CONTRIB/SNIP/chmod.c new file mode 100755 index 0000000..d74bef8 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/chmod.c @@ -0,0 +1,224 @@ +/* +** CHMOD.C - Retrieve or change a DOS file's attributes +** +** public domain demo by Bob Stout +** +** Notes: To expand command line arguments with wildcards, +** TC/TC++/BC++ - Link in WILDARGS.OBJ. +** MSC/QC - Link in SETARGV.OBJ. +** ZTC/C++ - Link in _MAINx.OBJ, where 'x' is the memory model. +** +** Allows file list(s) using standard "@file_list_name" convention. +*/ + +#include +#include +#include +#include +#include + +#define LAST_CHAR(s) (s)[strlen(s)-1] + +#if defined(__TURBOC__) + #include + #define FAR far +#else + #include + + #define BOOL(x) (!(!(x))) + #define FAR _far + + #if (defined(_MSC_VER) && (_MSC_VER >= 700)) || (defined(__SC__)) + // Make FP_xxx macros lvalues as in older versions + #undef FP_SEG + #undef FP_OFF + #define FP_SEG(fp) ((unsigned)((unsigned long)(fp) >> 16)) + #define FP_OFF(fp) ((unsigned)(fp && 0xffff)) + #endif + + int _chmod(const char *path, int func, ...) + { + union REGS regs; + struct SREGS sregs; + int atr = 0; + va_list args; + + if (0 != (func = BOOL(func))) + { + va_start(args, func); + atr = va_arg(args, int); + } + regs.x.ax = 0x4300 + func; + regs.x.dx = FP_OFF((char FAR *)path); + regs.x.cx = atr; + segread(&sregs); + sregs.ds = FP_SEG((char FAR *)path); + intdosx(®s, ®s, &sregs); + if (regs.x.cflag) + return -1; + if (func) + return atr; + else return regs.x.cx; + } + + #ifndef FA_RDONLY + #define FA_RDONLY _A_RDONLY + #endif + + #ifndef FA_HIDDEN + #define FA_HIDDEN _A_HIDDEN + #endif + + #ifndef FA_SYSTEM + #define FA_SYSTEM _A_SYSTEM + #endif + + #ifndef FA_ARCH + #define FA_ARCH _A_ARCH + #endif + + #ifndef FA_LABEL + #define FA_LABEL _A_VOLID + #endif + + #ifndef FA_DIREC + #define FA_DIREC _A_SUBDIR + #endif +#endif + +int attrib, /* Set up new attributes here */ + atr_setmask = 0, + atr_clrmask = -1, + flag = 0; /* Passed as func to _chmod() */ + +void usage(void) /* Tell 'em they messed up */ +{ + puts("Usage: CHMOD file [file [...file] [+switches] [-switches]"); + puts("Where switches are one or more of:"); + puts(" A: Archive"); + puts(" R: Read only"); + puts(" H: Hidden"); + puts(" S: System"); + puts("File lists may be specified with \"@file_list_name\""); + puts("With no switches, diplays current attributes."); + puts("Displayed attributes are as above plus:"); + puts(" D: Subdirectory"); + puts(" V: Volume label"); + exit(1); +} + +void setattr(char atr) /* Set bits in attribute */ +{ + switch (toupper(atr)) + { + case 'A': + atr_setmask |= FA_ARCH; + break; + case 'R': + atr_setmask |= FA_RDONLY; + break; + case 'S': + atr_setmask |= FA_SYSTEM; + break; + case 'H': + atr_setmask |= FA_HIDDEN; + break; + default: + usage(); + } +} + +void clrattr(char atr) /* Clear bits in attribute */ +{ + switch (toupper(atr)) + { + case 'A': + atr_clrmask &= ~FA_ARCH; + break; + case 'R': + atr_clrmask &= ~FA_RDONLY; + break; + case 'S': + atr_clrmask &= ~FA_SYSTEM; + break; + case 'H': + atr_clrmask &= ~FA_HIDDEN; + break; + default: + usage(); + } +} + +void show_atr(char *path) +{ + char astr[7], *ptr; + + if (-1 == (attrib = _chmod(strupr(path), 0))) + { +ATR_ERR: printf("\aCHMOD: Error! (file: %s)", path); + exit(-1); + } + attrib |= atr_setmask; + attrib &= atr_clrmask; + if (-1 == (attrib = _chmod(path, flag, attrib))) + goto ATR_ERR; + ptr = astr; + *ptr++ = (char)((attrib & FA_ARCH) ? 'A' : '.'); + *ptr++ = (char)((attrib & FA_RDONLY) ? 'R' : '.'); + *ptr++ = (char)((attrib & FA_SYSTEM) ? 'S' : '.'); + *ptr++ = (char)((attrib & FA_HIDDEN) ? 'H' : '.'); + *ptr++ = (char)((attrib & FA_DIREC) ? 'D' : '.'); + *ptr++ = (char)((attrib & FA_LABEL) ? 'V' : '.'); + *ptr = '\0'; + printf("%-15s %s\n", path, astr); +} + +int main (int argc, char *argv[]) +{ + int i, j; + + if (2 > argc) + usage(); + for (i = 1; i < argc; ++i) /* Build attribute masks */ + { + switch (*argv[i]) + { + case '+': + for (j = 1; argv[i][j]; ++j) + setattr(argv[i][j]); + flag = 1; + break; + case '-': + for (j = 1; argv[i][j]; ++j) + clrattr(argv[i][j]); + flag = 1; + break; + default: + break; /* Assume it's a file name */ + } + } + for (i = 1; i < argc; ++i) /* Scan filenames */ + { + if (strchr("+-", *argv[i])) + continue; + if ('@' == *argv[i]) + { + FILE *fp; + char buf[256], *ptr = &argv[i][1]; + + if (NULL == (fp = fopen(ptr, "r"))) + { + printf("\aCHMOD: Error opening %s\n", ptr); + return -1; + } + while (NULL != fgets(buf, 255, fp)) + { + LAST_CHAR(buf) = '\0'; /* Strip '\n' */ + show_atr(buf); + } + fclose(fp); + } + else show_atr(argv[i]); + } + return 0; +} diff --git a/reference/C/CONTRIB/SNIP/clock.c b/reference/C/CONTRIB/SNIP/clock.c new file mode 100755 index 0000000..4b0b52a --- /dev/null +++ b/reference/C/CONTRIB/SNIP/clock.c @@ -0,0 +1,200 @@ +/* CLOCK.H: prototypes/defines for the CLOCK.C file */ +/* + This file written in 1990 Jonathan R. Guthrie and placed in the + public domain +*/ + +int far startclock(int x, int y, int attr); +void far stopclock(void); + +#define CLOCK_OK 0 /* Clock was installed properly */ +#define CLOCK_ERR_INST -1 /* Clock is already installed */ +#define CLOCK_ERR_OOS -2 /* Clock would be off the screen */ + + +/* CLOCK.C: An on-screen clock generator */ +/* + This file written in 1990 Jonathan R. Guthrie and placed in the + public domain +*/ + +#include +#include +#include +#include +#include "clock.h" + +#define CLOCK 0x1c +#define TRUE 1 +#define FALSE 0 + +/* Now, the stuff needed for the for the on-screen clock */ + +static void interrupt (*oldvector)(void); +static void interrupt do_clock(void); +static void setstr(char *, int, size_t); + +static char timestuff[22], hours, oddfives, ticks, ticklimit; + +static int clockx, clocky, clockattr, installed = FALSE; + +int far startclock(int x, int y, int attr) +{ + time_t temptime; + struct tm *struct_time; + int bigx; + struct text_info r; + + /* The clock starting routine */ + + /* First, see if it's already installed */ + + if(installed) + return CLOCK_ERR_INST; + else installed = TRUE; + + /* Now, set assorted important module constants */ + + clockx = x; + clocky = y; + clockattr = attr; + + gettextinfo(&r); + + if((clockx < 0) || (clockx > r.screenwidth - 10) || + (clocky < 0) || (clocky > r.screenheight)) + { + installed = FALSE; + return CLOCK_ERR_OOS; + } + + /* Now, set the program's clock */ + + setstr(timestuff, clockattr, 22); + + time(&temptime); + struct_time = localtime(&temptime); + + oddfives = 0; + ticklimit = 17; + hours = (struct_time->tm_hour + 11) % 12 + 1; + timestuff[0] = (hours > 9) ? '1' : ' '; + timestuff[2] = '0' + hours % 10; + timestuff[4] = ':'; + timestuff[6] = '0' + struct_time->tm_min / 10; + timestuff[8] = '0' + struct_time->tm_min % 10; + timestuff[10] = ':'; + timestuff[12] = '0' + struct_time->tm_sec / 10; + timestuff[14] = '0' + struct_time->tm_sec % 10; + timestuff[16] = ' '; + timestuff[18] = (struct_time->tm_hour > 11) ? 'P' : 'A'; + timestuff[20] = 'M'; + + /* Now, initialize the clock as displayed on the screen */ + + puttext(clockx, clocky, clockx+10, clocky, timestuff); + + /* Finally, set the vector to point to the clock routine */ + + disable(); + oldvector = getvect(CLOCK); + setvect(CLOCK, do_clock); + enable(); + return CLOCK_OK; +} + +static void interrupt do_clock(void) +{ + ++ticks; + if(ticks > ticklimit) /* Then, it's time to update the seconds */ + { + ticks = 0; + + /* First, handle the fractional Hz part */ + + ++oddfives; + if (5 == oddfives) + { + oddfives = 0; + ticklimit = 18; + } + else + { + ticklimit = 17; + } + + /* Now, handle the seconds count */ + + ++timestuff[14]; + + if (timestuff[14] > '9') + { + timestuff[14] = '0'; + + /* Now, handle the tens of seconds count */ + + ++timestuff[12]; + if (timestuff[12] > '5') + { + timestuff[12] = '0'; + + /* Now, handle the minutes count */ + + ++timestuff[8]; + if (timestuff[8] > '9') + { + timestuff[8] = '0'; + + /* Now, handle the ten minutes count */ + + ++timestuff[6]; + if (timestuff[6] > '5') + { + timestuff[6] = '0'; + + /* Now, handle the hours count */ + + ++hours; + if(12 == hours) + if ('P' == timestuff[18]) + timestuff[18] = 'A'; + else timestuff[18] = 'P'; + + if(hours > 12) + hours = 1; + + timestuff[0] = (hours > 9) ? '1' : ' '; + timestuff[2] = '0' + hours % 10; + } + } + } + } + + /* Now, update the display */ + + puttext(clockx, clocky, clockx+10, clocky, timestuff); + } +} + +void far stopclock(void) +{ + if(installed) + { + disable(); + setvect(CLOCK, oldvector); + enable(); + installed = FALSE; + } +} + +static void setstr(char *s, int ch, size_t n) +{ + size_t i; + + for(i=0 ; i + +#define plural_text(n) &"s"[(1 == (n))] +#define plural_text2(n) &"es"[(1 == (n)) << 1] + +main(int argc, char *argv[]) +{ + int i, n = argc - 1; + + printf("You passed %d argument%s on the command line.", + n, plural_text(n)); + + if (argc > 1) + { + puts(" They are:"); + for (i = 1; i < argc; ++i) + { + printf("\nArgument #%d:\n Text: \"%s\"\n Value: %d\n", + i, argv[i], atoi(argv[i])); + } + } + else putchar('\n'); + return 0; +} diff --git a/reference/C/CONTRIB/SNIP/coldboot.asm b/reference/C/CONTRIB/SNIP/coldboot.asm new file mode 100755 index 0000000..828c79d --- /dev/null +++ b/reference/C/CONTRIB/SNIP/coldboot.asm @@ -0,0 +1,42 @@ +; by: David Nugent via ECPROG echo +; +; works VERY reliably under all the protected mode environments I've +; tried (namely DV and PC-MOS). Haven't tried VM386 or NX386 yet, but +; I'm hopeful.... ;-) + + +BIOS_POST equ 0472H ; POST (warm boot) flag + + + xor BX,BX ; AL=1 for warm boot, 0 for cold + mov ES,BX + cmp AL,1 + jnz @NcB + mov AX,1234H ; Avoid POST +@NcB: + mov ES:[BIOS_POST],AX ; Install flag + + cli ; Reboot + xor AX,AX + mov DS,AX + mov ES,AX + mov SS,AX + mov SP,AX +@cP: + in AL,64H ; Wait on AT keyboard controller + test AL,2 + jne @cP + + xor AL,AL ; Try reset lines + out 64H,AL + iodelay + mov AL,0FEh + out 64H,AL + iodelay + mov AX,0002H ; Jump to reset vector + push AX ; via IRET + mov AX,0F000H + push AX + mov AX,0FFF0H + push AX + iret diff --git a/reference/C/CONTRIB/SNIP/combin.c b/reference/C/CONTRIB/SNIP/combin.c new file mode 100755 index 0000000..e9b5687 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/combin.c @@ -0,0 +1,66 @@ +/* +** Compute C(n,m) = the number of combinations of n items, +** taken m at a time. +** +** Written by Thad Smith III, Boulder County, CO. +** Released to the Public Domain 10/14/91. +** +** The def of this function is +** C(n,m) = n! / (m! * (n-m)!). +** Computing this formula can cause overflow for large values of n, +** even when C(n,m) would be defined. +** +** The first version will not overflow if C(n,m) * (n-m+1) < ULONG_MAX. +** The second version will not overflow if C(n,m) < ULONG_MAX, but +** is slightly more complex. +** Function domain: n >= 0, 0 <= m <= n. +** +** Both versions work by reducing the product as it is computed. It +** relies on the property that the product on n consecutive integers +** must be evenly divisible by n. +** +** The first version can be changed to make cnm and the return value +** double to extend the range of the function. +*/ + +unsigned long ncomb1 (int n, int m) +{ + unsigned long cnm = 1UL; + int i; + + if (m*2 >n) m = n-m; + for (i=1 ; i <= m; n--, i++) + cnm = cnm * n / i; + return cnm; +} + +unsigned long ncomb2 (int n, int m) +{ + unsigned long cnm = 1UL; + int i, f; + + if (m*2 >n) m = n-m; + for (i=1 ; i <= m; n--, i++) + { + if ((f=n) % i == 0) + f /= i; + else cnm /= i; + cnm *= f; + } + return cnm; +} + +#ifdef TEST + +#include +#include + +main (int argc, char *argv[]) { + int n,m; + n = atoi (argv[1]); + m = atoi (argv[2]); + printf ("ncomb1 = %lu, ncomb2 = %lu\n", ncomb1(n,m), ncomb2(n,m)); + return 0; +} + +#endif diff --git a/reference/C/CONTRIB/SNIP/commafmt.c b/reference/C/CONTRIB/SNIP/commafmt.c new file mode 100755 index 0000000..b5d24f7 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/commafmt.c @@ -0,0 +1,82 @@ +/* +** COMMAFMT.C +** +** Public domain by Bob Stout +** +** Notes: 1. Use static buffer to eliminate error checks on buffer overflow +** and reduce code size. +** 2. By making the numeric argument a long and prototyping it before +** use, passed numeric arguments will be implicitly cast to longs +** thereby avoiding int overflow. +** 3. Use the thousands grouping and thousands separator from the +** ANSI locale to make this more robust. +*/ + +#include +#ifdef TEST + #include +#endif + +#define NUL '\0' + +size_t commafmt(char *buf, /* Buffer for formatted string */ + int bufsize, /* Size of buffer */ + long N) /* Number to convert */ +{ + int len = 1, posn = 1, sign = 1; + char *ptr = buf + bufsize - 1; + + if (2 > bufsize) + { +ABORT: *buf = NUL; + return 0; + } + + *ptr-- = NUL; + --bufsize; + if (0L > N) + { + sign = -1; + N = -N; + } + + for ( ; len <= bufsize; ++len, ++posn) + { + *ptr-- = (char)((N % 10L) + '0'); + if (0L == (N /= 10L)) + break; + if (0 == (posn % 3)) + { + *ptr-- = ','; + ++len; + } + if (len >= bufsize) + goto ABORT; + } + + if (0 > sign) + { + if (0 == bufsize) + goto ABORT; + *ptr-- = '-'; + ++len; + } + + strcpy(buf, ++ptr); + return (size_t)len; +} + +#ifdef TEST + +void main(int argc, char *argv[]) +{ + size_t len; + char buf[20]; + long N; + + N = strtol(argv[1], NULL, 10); + len = commafmt(buf, 20, N); + printf("%s converts to %s and returned %d\n", argv[1], buf, len); +} + +#endif diff --git a/reference/C/CONTRIB/SNIP/commconv.c b/reference/C/CONTRIB/SNIP/commconv.c new file mode 100755 index 0000000..67287b4 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/commconv.c @@ -0,0 +1,97 @@ +/* + * COMMCONV.C + * Change C++ -comments to C-comments + * + * Public domain by Jari Laaksonen (2:221/105.11), 22 Dec 1992 + */ + +#include + +int main (int argc, char **argv) +{ + int Char, cpp_comment = 0, c_comment = 0, in_string = 0; + char CannotOpen[] = "\nCannot open %s\n\n"; + FILE *InFile, *OutFile = stdout; + + if (argc < 2) + { + fprintf (stderr, "USAGE: COMMCONV InFile [OutFile]\n"); + return (1); + } + if ((InFile = fopen (argv[1], "r")) == NULL) + { + fprintf (stderr, CannotOpen, argv[1]); + return (3); + } + + if (argc == 3) + { + if ((OutFile = fopen (argv[2], "w")) == NULL) + { + fprintf (stderr, CannotOpen, argv[2]); + OutFile = stdout; /* if can't open, output goes to stdout instead */ + } + } + + while ((Char = fgetc (InFile)) != EOF) + { + fputc (Char, OutFile); + + if (Char == '\"') + in_string = ! in_string; /* toggle flag */ + + if (in_string) /* we are in a string now */ + continue; + + if (Char == '/') /* slash */ + { + Char = fgetc (InFile); /* check next char */ + if (Char == '/') /* is it start of C++ comment */ + { + Char = '*'; /* change it to C comment */ + cpp_comment = 1; + } + else if (Char == '*') /* is it start of C comment */ + c_comment = 1; + + fputc (Char, OutFile); + + if (c_comment || cpp_comment) /* inside C or C++ comment */ + { + while ((Char = fgetc (InFile)) != '\n') /* rest of the line */ + { + if (Char == '*' && c_comment) + { + int Ch = fgetc (InFile); /* check next char */ + if (Ch == '/') /* is it end of C comment */ + c_comment = 0; + ungetc (Ch, InFile); /* put it back to stream */ + } + fputc (Char, OutFile); + } + if (cpp_comment) + { + fputs (" *", OutFile); /* put ending C comment mark */ + if (c_comment) + fputc (' ', OutFile); + fputc ('/', OutFile); + cpp_comment = 0; + } + fputc ('\n', OutFile); + } + } + else if (Char == '*' && c_comment) + { + Char = fgetc (InFile); + if (Char == '/') /* is it end of C comment */ + c_comment = 0; + fputc (Char, OutFile); + } + } /* while end */ + + if (argc == 3) + fclose (OutFile); + fclose (InFile); + + return 0; +} diff --git a/reference/C/CONTRIB/SNIP/compiler.c b/reference/C/CONTRIB/SNIP/compiler.c new file mode 100755 index 0000000..5ee62a6 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/compiler.c @@ -0,0 +1,46 @@ +/* +** Tests for popular PC compilers and versions +*/ + +#include + +void main(void) /* Actually, void main() is non-ANSI/ISO */ +{ + int version; + +#if defined(__ZTC__) + #ifdef __SC__ + printf("Symantec C++ ver. %x.%x\n", __SC__ >> 8, __SC__ & 0xff); + #else + printf("Zortech C++ ver. %x.%xr%x\n", + __ZTC__ >> 8, (__ZTC__ >> 4) & 0xf, __ZTC__ & 0xf); + #endif +#elif defined(__WATCOMC__) + printf("Watcom C/C++ ver. %d.%d\n", + __WATCOMC__ / 100, __WATCOMC__ % 100); +#elif defined(__TURBOC__) + version = __TURBOC__; + if (0x295 > version) + { + printf("Borland Turbo C ver. %x.%02x\n", + version >> 8, version & 0xff); + } + else if (0x400 <= version) + { + printf("Borland C++ ver. %x.%x\n", + (version >> 8) - 1, (version & 0xff) >> 4); + } + else if (0x297 > version) + printf("Borland Turbo C++ ver. 1.%02x\n", version - 0x295); + else printf("Borland C++ ver. 2.%02x\n", version - 0x297); +#elif defined(_QC) + printf("Microsoft Quick C ver. %d.%d\n", _QC / 100, _QC % 100); +#elif defined(_MSC_VER) + printf("Microsoft C(/C++) ver. %d.%d\n", + _MSC_VER / 100, _MSC_VER % 100); +#elif defined(__POWERC) + printf ("MIX Power C ver. %d\n", __POWERC); +#else + puts("Unknown compiler!"); +#endif +} diff --git a/reference/C/CONTRIB/SNIP/cpucheck.asm b/reference/C/CONTRIB/SNIP/cpucheck.asm new file mode 100755 index 0000000..f5ae682 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/cpucheck.asm @@ -0,0 +1,78 @@ + page 55, 132 + +; FUNCTION: cpu_check +; +; Attempt to discover the type of CPU. Use MASM 5.1 or greater. +; Returns 86 for 8088/8086, 286 for 80286, 386 for 80386/80486. +; +; Requires MASM 5.1 or later or equivalent +; +; Assemble with: MASM /Mx /z ... +; TASM /jMASM /mx /z ... +; + +% .MODEL memodel,C ;Add model support via + ;command line macros, e.g. + ;MASM /Dmemodel=LARGE + + .CODE +; +; int cpu_check(void) - returns 86, 186, 286, 386 +; + + PUBLIC cpu_check + +cpu_check PROC USES BX + pushf + xor ax,ax ; zero ax + push ax + popf ; try to put 0 into flags + pushf + pop ax ; see what went in flags + and ax,0f000h ; mask off high flag bits + cmp ax,0f000h ; was high nibble ones + je _86 ; is 8086 or 8088 + push sp ; see if sp is updated + pop bx ; before or after it is + cmp bx,sp ; pushed + jne _186 + mov ax,0f000h ; try to set high bits + push ax + popf ; in the flags + pushf + pop ax ; look at actual flags + and ax,0f000h ; any high bits set? + je _286 ; is 80286 +_386: + .386 ; enable 386 instructions + + pushfd ; save extended flags + mov eax,040000h + push eax ; push 40000h onto stack + popfd ; pop extended flags + pushfd ; push extended flags + pop eax ; put in eax + and eax,040000h ; is bit 18 set? + jne _486 ; yes, it's a 486 + mov ax,386 ; no, it's a 386 + jmp _386x +_486: + mov ax,486 +_386x: + popfd ; clean the stack + jmp ccexit +_286: + mov ax,286 ; is an 80286 + jmp ccexit +_186: + mov ax,186 ; is an 80188/80186 + jmp ccexit +_86: + mov ax,86 ; is an 8088/8086 +ccexit: + popf ; restore original flags + ret ; return + +cpu_check ENDP + + end diff --git a/reference/C/CONTRIB/SNIP/crc-16.c b/reference/C/CONTRIB/SNIP/crc-16.c new file mode 100755 index 0000000..e1f3165 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/crc-16.c @@ -0,0 +1,37 @@ +#define POLY 0x8408 +/* +// 16 12 5 +// this is the CCITT CRC 16 polynomial X + X + X + 1. +// This works out to be 0x1021, but the way the algorithm works +// lets us use 0x8408 (the reverse of the bit pattern). The high +// bit is always assumed to be set, thus we only use 16 bits to +// represent the 17 bit value. +*/ + +unsigned short crc16(char *data_p, unsigned short length) +{ + unsigned char i; + unsigned int data; + unsigned int crc = 0xffff; + + if (length == 0) + return (~crc); + + do + { + for (i=0, data=(unsigned int)0xff & *data_p++; + i < 8; + i++, data >>= 1) + { + if ((crc & 0x0001) ^ (data & 0x0001)) + crc = (crc >> 1) ^ POLY; + else crc >>= 1; + } + } while (--length); + + crc = ~crc; + data = crc; + crc = (crc << 8) | (data >> 8 & 0xff); + + return (crc); +} diff --git a/reference/C/CONTRIB/SNIP/crc-16f.c b/reference/C/CONTRIB/SNIP/crc-16f.c new file mode 100755 index 0000000..ad45a4a --- /dev/null +++ b/reference/C/CONTRIB/SNIP/crc-16f.c @@ -0,0 +1,130 @@ +/* + * Calculate, intelligently, the CRC of a dataset incrementally given a + * buffer full at a time. + * Initialize crc to 0 for XMODEM, -1 for CCITT. + * + * Usage: + * newcrc = updcrc( oldcrc, bufadr, buflen ) + * unsigned int oldcrc, buflen; + * char *bufadr; + * + * Compile with -DTEST to generate program that prints CRC of stdin to stdout. + * Compile with -DMAKETAB to print values for crctab to stdout + */ + + /* the CRC polynomial. This is used by XMODEM (almost CCITT). + * If you change P, you must change crctab[]'s initial value to what is + * printed by initcrctab() + */ +#define P 0x1021 + + /* number of bits in CRC: don't change it. */ +#define W 16 + + /* this the number of bits per char: don't change it. */ +#define B 8 + +static unsigned short crctab[1<>(W-B)) ^ *cp++]; + + return( crc ); +} + +#ifdef MAKETAB +main() +{ + initcrctab(); +} + +initcrctab() +{ + register b, v, i; + + for( b = 0; b <= (1<= 0; ) + v = v&0x8000 ? (v<<1)^P : v<<1; + crctab[b] = v; + + printf( "0x%04x,", v & 0xFFFF ); + if( (b&7) == 7 ) + printf("\n" ); + else printf(" "); + } +} +#endif + +#ifdef TEST + +#include +#include + +#define MAXBUF 4096 + +void main(int argc, char **argv) +{ + int fd = 0; + int nr; + char buf[MAXBUF]; + unsigned short crc; + + if( argc > 1 ) + { + if( (fd = open( argv[1], O_RDONLY )) < 0 ) + { + perror( argv[1] ); + exit( -1 ); + } + } + crc = 0; + while( (nr = read( fd, buf, MAXBUF )) > 0 ) + crc = updcrc( crc, buf, nr ); + printf( "%04x\n", crc ); + if( nr != 0 ) + perror( "reading" ); +} + +#endif diff --git a/reference/C/CONTRIB/SNIP/crc_32.c b/reference/C/CONTRIB/SNIP/crc_32.c new file mode 100755 index 0000000..386e2ec --- /dev/null +++ b/reference/C/CONTRIB/SNIP/crc_32.c @@ -0,0 +1,172 @@ +/* Crc - 32 BIT ANSI X3.66 CRC checksum files */ + +#include +#define OK 0 +#define ERROR (-1) + +/**********************************************************************\ +|* Demonstration program to compute the 32-bit CRC used as the frame *| +|* check sequence in ADCCP (ANSI X3.66, also known as FIPS PUB 71 *| +|* and FED-STD-1003, the U.S. versions of CCITT's X.25 link-level *| +|* protocol). The 32-bit FCS was added via the Federal Register, *| +|* 1 June 1982, p.23798. I presume but don't know for certain that *| +|* this polynomial is or will be included in CCITT V.41, which *| +|* defines the 16-bit CRC (often called CRC-CCITT) polynomial. FIPS *| +|* PUB 78 says that the 32-bit FCS reduces otherwise undetected *| +|* errors by a factor of 10^-5 over 16-bit FCS. *| +\**********************************************************************/ + +/* Need an unsigned type capable of holding 32 bits; */ + +typedef unsigned long int UNS_32_BITS; + +/* Copyright (C) 1986 Gary S. Brown. You may use this program, or + code or tables extracted from it, as desired without restriction.*/ + +/* First, the polynomial itself and its table of feedback terms. The */ +/* polynomial is */ +/* X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 */ +/* Note that we take it "backwards" and put the highest-order term in */ +/* the lowest-order bit. The X^32 term is "implied"; the LSB is the */ +/* X^31 term, etc. The X^0 term (usually shown as "+1") results in */ +/* the MSB being 1. */ + +/* Note that the usual hardware shift register implementation, which */ +/* is what we're using (we're merely optimizing it by doing eight-bit */ +/* chunks at a time) shifts bits into the lowest-order term. In our */ +/* implementation, that means shifting towards the right. Why do we */ +/* do it this way? Because the calculated CRC must be transmitted in */ +/* order from highest-order term to lowest-order term. UARTs transmit */ +/* characters in order from LSB to MSB. By storing the CRC this way, */ +/* we hand it to the UART in the order low-byte to high-byte; the UART */ +/* sends each low-bit to hight-bit; and the result is transmission bit */ +/* by bit from highest- to lowest-order term without requiring any bit */ +/* shuffling on our part. Reception works similarly. */ + +/* The feedback terms table consists of 256, 32-bit entries. Notes: */ +/* */ +/* 1. The table can be generated at runtime if desired; code to do so */ +/* is shown later. It might not be obvious, but the feedback */ +/* terms simply represent the results of eight shift/xor opera- */ +/* tions for all combinations of data and CRC register values. */ +/* */ +/* 2. The CRC accumulation logic is the same for all CRC polynomials, */ +/* be they sixteen or thirty-two bits wide. You simply choose the */ +/* appropriate table. Alternatively, because the table can be */ +/* generated at runtime, you can start by generating the table for */ +/* the polynomial in question and use exactly the same "updcrc", */ +/* if your application needn't simultaneously handle two CRC */ +/* polynomials. (Note, however, that XMODEM is strange.) */ +/* */ +/* 3. For 16-bit CRCs, the table entries need be only 16 bits wide; */ +/* of course, 32-bit entries work OK if the high 16 bits are zero. */ +/* */ +/* 4. The values must be right-shifted by eight bits by the "updcrc" */ +/* logic; the shift must be unsigned (bring in zeroes). On some */ +/* hardware you could probably optimize the shift in assembler by */ +/* using byte-swap instructions. */ + +static UNS_32_BITS crc_32_tab[] = { /* CRC polynomial 0xedb88320 */ +0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, +0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, +0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, +0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, +0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, +0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, +0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, +0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, +0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, +0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, +0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, +0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, +0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, +0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, +0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, +0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, +0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, +0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, +0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, +0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, +0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, +0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, +0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, +0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, +0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, +0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, +0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, +0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, +0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, +0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, +0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, +0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, +0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, +0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, +0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, +0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, +0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, +0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, +0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, +0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, +0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, +0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, +0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d +}; + +#define UPDC32(octet, crc) (crc_32_tab[((crc)\ + ^ (octet)) & 0xff] ^ ((crc) >> 8)) + +main(int argc, char *argp[]) +{ + register errors = 0; + + while(--argc > 0) + errors |= crc32file( *++argp); + return(errors != 0); +} + +crc32file(char *name) +{ + register FILE *fin; + register unsigned long oldcrc32; + register unsigned long crc32; + register unsigned long oldcrc; + register c; + register long charcnt; + + oldcrc32 = 0xFFFFFFFF; charcnt = 0; +#ifdef MSDOS + if ((fin=fopen(name, "rb"))==NULL) +#else + if ((fin=fopen(name, "r"))==NULL) +#endif + { + perror(name); + return ERROR; + } + while ((c=getc(fin))!=EOF) + { + ++charcnt; + oldcrc32 = UPDC32(c, oldcrc32); + } + + if (ferror(fin)) + { + perror(name); + charcnt = -1; + } + fclose(fin); + + crc32 = oldcrc32; oldcrc = oldcrc32 = ~oldcrc32; + +/**/ + crc32 = UPDC32((oldcrc32 & 0377), crc32); oldcrc32 >>=8; + crc32 = UPDC32((oldcrc32 & 0377), crc32); oldcrc32 >>=8; + crc32 = UPDC32((oldcrc32 & 0377), crc32); oldcrc32 >>=8; + crc32 = UPDC32((oldcrc32 & 0377), crc32); oldcrc32 >>=8; + printf("%08lX ", crc32); +/**/ + + printf("%08lX %7ld %s\n", oldcrc, charcnt, name); + + return OK; +} diff --git a/reference/C/CONTRIB/SNIP/crypt.c b/reference/C/CONTRIB/SNIP/crypt.c new file mode 100755 index 0000000..cbfac15 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/crypt.c @@ -0,0 +1,98 @@ +/****************************************************************/ +/* */ +/* S-CODER - Encrypt/decrypt data */ +/* */ +/* Copyright 1987-1989 by Robert B. Stout dba MicroFirm */ +/* */ +/* Originally written by Bob Stout with modifications */ +/* suggested by Mike Smedley. */ +/* */ +/* This code may be used freely in any program for any */ +/* application, personal or commercial. */ +/* */ +/* Current commercial availability: */ +/* */ +/* 1. MicroFirm Toolkit ver 3.00: LYNX and CRYPT utilities */ +/* 2. CXL libraries (MSC, TC, ZTC/C++, PC): fcrypt() */ +/* dedicated file encryption function */ +/* 3. SMTC & MFLZT libraries: crypt() function */ +/* */ +/****************************************************************/ + +char *cryptext; /* The actual encryption/decryption key */ +int crypt_ptr = 0; /* Circular pointer to elements of key */ +int crypt_length; /* Set externally to strlen(cryptext) */ + +/* NOTES: cryptext should be set and qualified (to something over + 5-6 chars, minimum) by the calling program, which should + also set crypt_ptr in the range of 0 to strlen(cryptext) + before each use. If crypt() is used to encrypt several + buffers, cryptext should be reloaded and crypt_ptr reset + before each buffer is encrypted. The encryption is both + reversible - to decrypt data, pass it back through crypt() + using the original key and original initial value of + crypt_ptr - and multiple passes are commutative. +*/ + +/**** Encrypt/decrypt buffer datum ******************************/ +void crypt(unsigned char *buf) +{ + *buf ^= cryptext[crypt_ptr] ^ (cryptext[0] * crypt_ptr); + cryptext[crypt_ptr] += ((crypt_ptr < (crypt_length - 1)) ? + cryptext[crypt_ptr + 1] : cryptext[0]); + if (!cryptext[crypt_ptr]) + cryptext[crypt_ptr] += 1; + if (++crypt_ptr >= crypt_length) + crypt_ptr = 0; +} + +/**** Encrypt/decrypt buffer ************************************/ +void bufcrypt(unsigned char *buf, long length) +{ + while (length--) + crypt(*buf++) +} + +#ifdef TEST + +#include +#include + +int main(int argc, char *argv[]) +{ + static char buf[16384]; + size_t len, i; + FILE *in, *out; + + if (4 > argc) + { + puts("Usage: CRYPT password infile outfile"); + return -1; + } + cryptext = argv[1]; + crypt_length = strlen(cryptext); + if (NULL == (in = fopen(argv[2], "rb"))) + { + printf("Can't open %s for input\n", argv[2]); + return -1; + } + if (NULL == (out = fopen(argv[3], "wb"))) + { + printf("Can't open %s for output\n", argv[3]); + return -1; + } + do + { + if (0 != (len = fread(buf, 1, 16384, in))) + { + for (i = 0; i < len; ++i) + crypt(&buf[i]); + fwrite(buf, 1, len, out); + } + } while (len); + fclose(in); + fclose(out); + return 0; +} + +#endif diff --git a/reference/C/CONTRIB/SNIP/ctrlprnt.c b/reference/C/CONTRIB/SNIP/ctrlprnt.c new file mode 100755 index 0000000..0ae15d1 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/ctrlprnt.c @@ -0,0 +1,40 @@ +/* +** Print a line of text, displaying Ctrl characters using leading carets +** public domain by Bob Stout +*/ + +void ctrl_print(char *line) +{ + while (*line) + { + if (' ' > *line) + { + putchar('^'); + putchar('@' + (*line++)); + } + else putchar(*line++); + } + if (!strcmp((line - 2), "\x0d\x0a") || !strcmp((line - 2), "\x0a\x0d")) + putchar('\n'); +} + +#ifdef TEST + +#include +#include +#include +#include + +void main(void) +{ + char *p, *test = "This is a test"; + + for (p = strupr(test); *p; ++p) + { + if (isalpha(*p)) + *p = *p - 64; + } + ctrl_print(test); +} + +#endif /* TEST */ diff --git a/reference/C/CONTRIB/SNIP/cubic.c b/reference/C/CONTRIB/SNIP/cubic.c new file mode 100755 index 0000000..cced533 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/cubic.c @@ -0,0 +1,61 @@ +/* +** CUBIC.C - Solve a cubic polynomial +** public domain by Ross Cottrell +*/ + +#include +#include + +void SolveCubic(double a, + double b, + double c, + double d, + int *solutions, + double *x) +{ + long double a1 = b/a, a2 = c/a, a3 = d/a; + long double Q = (a1*a1 - 3.0*a2)/9.0; + long double R = (2.0*a1*a1*a1 - 9.0*a1*a2 + 27.0*a3)/54.0; + double R2_Q3 = R*R - Q*Q*Q; + + double theta; + + if (R2_Q3 <= 0) + { + *solutions = 3; + theta = acos(R/sqrt(Q*Q*Q)); + x[0] = -2.0*sqrt(Q)*cos(theta/3.0) - a1/3.0; + x[1] = -2.0*sqrt(Q)*cos((theta+2.0*M_PI)/3.0) - a1/3.0; + x[2] = -2.0*sqrt(Q)*cos((theta+4.0*M_PI)/3.0) - a1/3.0; + } + else + { + *solutions = 1; + x[0] = pow(sqrt(R2_Q3)+fabs(R), 1/3.0); + x[0] += Q/x[0]; + x[0] *= (R < 0.0) ? 1 : -1; + x[0] -= a1/3.0; + } +} + +#ifdef TEST + +int main(void) +{ + double a1 = 1.0, b1 = -10.5, c1 = 32.0, d1 = -30.0; + double a2 = 1.0, b2 = -4.5, c2 = 17.0, d2 = -30.0; + double x[3]; + int solutions; + + SolveCubic(a1, b1, c1, d1, &solutions, x); + + /* should get 3 solutions: 2, 6 & 2.5 */ + + SolveCubic(a2, b2, c2, d2, &solutions, x); + + /* should get 1 solution: 2.5 */ + + return 0; +} + +#endif /* TEST */ diff --git a/reference/C/CONTRIB/SNIP/cursize.c b/reference/C/CONTRIB/SNIP/cursize.c new file mode 100755 index 0000000..18d8172 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/cursize.c @@ -0,0 +1,66 @@ +/* +** Program to set the size of the cursor +** +** Public domain demonstration by Bob Jarvis +*/ + +#include /* puts() */ +#include /* int86(), union REGS */ +#include /* exit(), atoi() */ + +char *help = "CURSIZE - sets the cursor size.\n" + "Usage:\n" + " CURSIZE \n" + "where\n" + " top-line = top line of cursor within character cell\n" + " bottom-line = bottom line\n" + "Example:\n" + " CURSIZE 7 8 \n" + " CURSIZE 32 32 "; + +void cursor_size(int top_line, int bottom_line) +{ + union REGS regs; + + regs.h.ah = 1; + regs.h.ch = (unsigned char)top_line; + regs.h.cl = (unsigned char)bottom_line; + + int86(0x10,®s,®s); +} + +void get_cursor_size(int *top_line, int *bottom_line) +{ + union REGS regs; + + regs.h.ah = 3; + regs.h.bh = 0; + int86(0x10, ®s, ®s); + + *top_line = regs.h.ch; + *bottom_line = regs.h.cl; + + return; +} + +void main(int argc, char *argv[]) +{ + int top, bottom; + + if(argc < 3) + { + puts(help); + exit(1); + } + + top = atoi(argv[1]); + bottom = atoi(argv[2]); + + cursor_size(top,bottom); + + top = bottom = -1; + + get_cursor_size(&top, &bottom); + + printf("top = %d bottom = %d\n", top, bottom); +} diff --git a/reference/C/CONTRIB/SNIP/cursor.c b/reference/C/CONTRIB/SNIP/cursor.c new file mode 100755 index 0000000..ce5b04e --- /dev/null +++ b/reference/C/CONTRIB/SNIP/cursor.c @@ -0,0 +1,52 @@ +/*****************************************************************/ +/** CURSOR() **/ +/** ARGUMENTS: A char variable identifiny what to do with **/ +/** the cursor. **/ +/** RETURN: none **/ +/** **/ +/** DESCRIPTION: This function receives a character which **/ +/** tells it to do one of several things. **/ +/** Turn the cursor on or off, or save the **/ +/** cursor positon, or restore the position. **/ +/** **/ +/** BY Bill Wilkie, 1988 **/ +/*****************************************************************/ + +#include + +static int position; /* global to hold cursor postion */ + +void cursor(char tmp) +{ + union REGS inregs,outregs; /* cpu registers */ + + switch(tmp) + { + case 'h' : /* CURSOR OFF */ + inregs.h.ah = 1; /* set cursor size */ + inregs.h.ch = 0x20; /* set bit turns cursor off */ + int86(0x10,&inregs,&outregs); + break; + + case 's' : /* SAVE CURSOR POSITION */ + inregs.h.ah = 3; /* read cursor positon and size */ + inregs.h.bh = 0; /* from page zero */ + int86(0x10,&inregs,&outregs); + position = outregs.x.dx; /* store positon */ + break; + + case 'r' : /* RESTORE CURSOR POSITON */ + inregs.h.ah = 2; /* set cursor positon */ + inregs.h.bh = 0; /* on page zero */ + inregs.x.dx = position; /* at this old position */ + int86(0x10,&inregs,&outregs); + break; + + case 'o' : /* CURSOR ON */ + inregs.h.ah = 1; /* set cursor size */ + inregs.h.ch = 6; /* cursor start line */ + inregs.h.cl = 7; /* cursor end line */ + int86(0x10,&inregs,&outregs); + break; + } +} diff --git a/reference/C/CONTRIB/SNIP/daynum.c b/reference/C/CONTRIB/SNIP/daynum.c new file mode 100755 index 0000000..b2e9461 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/daynum.c @@ -0,0 +1,104 @@ +/* +** DAYNUM.C - Functions to return statistics about a given date. +** +** public domain by Bob Stout - uses Ray Gardner's SCALDATE.C +*/ + +#include "scaldate.h" + +static long jan1date; + +/* +** Determine if a given date is valid +*/ + +int valiDate(unsigned yr, unsigned mo, unsigned day) +{ + unsigned int days[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + + if (1 > mo || 12 < mo) + return 0; + if (1 > day || day > (days[mo - 1] + (2 == mo && isleap(yr)))) + return 0; + else return 1; +} + +/* +** Return the day of the week +*/ + +int dow(unsigned yr, unsigned mo, unsigned day) +{ + +#if (!ISO) /* Sunday(0) -> Saturday(6) (i.e. U.S.) calendars */ + return (ymd_to_scalar(yr, mo, day) % 7L); +#else /* International Monday(0) -> Sunday(6) calendars */ + return ((ymd_to_scalar(yr, mo, day) - 1L) % 7L); +#endif +} + +/* +** Return the day of the year (1 - 365/6) +*/ + +int daynum(int year, int month, int day) +{ + jan1date = ymd_to_scalar(year, 1, 1); + return (int)(ymd_to_scalar(year, month, day) - jan1date + 1L); +} + +/* +** Return the week of the year (1 - 52, 0 - 52 if ISO) +*/ + +int weeknum(int year, int month, int day) +{ + int wn, j1n, dn = daynum(year, month, day); + + dn += (j1n = (int)((jan1date - (long)ISO) % 7L)) - 1; + wn = dn / 7; + if (ISO) + wn += (j1n < 4); + else ++wn; + return wn; +} + +#ifdef TEST + +#include +#include + +void do_err(void); + +void main(int argc, char *argv[]) +{ + int day, month, year; + char *days[] = +#if (!ISO) + {"Sunday", "Monday", "Tuesday", "Wednesday", + "Thursday", "Friday", "Saturday"}; +#else + {"Monday", "Tuesday", "Wednesday", "Thursday", + "Friday", "Saturday", "Sunday"}; +#endif + + if (4 > argc) + { + puts("Usage: DAYNUM month day year"); + return; + } + + month = atoi(argv[1]); + day = atoi(argv[2]); + year = atoi(argv[3]); + if (100 > year) + year += 1900; + + if (!valiDate(year, month, day)) + printf("%d/%d/%d is invalid!\n", month, day, year); + else printf("%d/%d/%d is a %s, day #%d in week %d\n", month, day, year, + days[dow(year, month, day)], daynum(year, month, day), + weeknum(year, month, day)); +} + +#endif /* TEST */ diff --git a/reference/C/CONTRIB/SNIP/dbl2long.c b/reference/C/CONTRIB/SNIP/dbl2long.c new file mode 100755 index 0000000..e8f422a --- /dev/null +++ b/reference/C/CONTRIB/SNIP/dbl2long.c @@ -0,0 +1,64 @@ +/* +** DBL2LONG.C - Functions to round doubles to longs +** Public domain by Ross G. Cottrell, June 1992 +*/ + +#include +#include +#include + +/* Assume IEEE doubles, little-endian CPU, 32-bit 2's complement longs. */ +/* (Actually, the assumptions made here aren't quite that gross.) */ + +unsigned long dbl2ulong(double t) +{ + assert(1 == FLT_ROUNDS); + t += 1.0 / DBL_EPSILON; + return *(unsigned long *)&t; +} + +long dbl2long(double t) +{ + assert(1 == FLT_ROUNDS); + t += 1.0 / DBL_EPSILON + 2.0 * (LONG_MAX + 1.0); + return *(long *)&t; +} + +#ifdef TEST + +#include +#include + +int main(int argc, char **argv) +{ + while (*++argv) + { + printf("'%s', as a long: %ld, as an unsigned long: %lu\n", + *argv, dbl2long(atof(*argv)), dbl2ulong(atof(*argv))); + } + return 0; +} + +#endif /* TEST */ + +/* + +EXPLANATION: + +The offset of 1.0/DBL_EPSILON forces the least significant bit of the +mantissa to represent the integer 1. This may not work on all formats of +doubles, but I think it's a safe bet for IEEE compliant doubles, and any +other floating point format with a radix of 2. When this offset is added, +the number should be rounded to the nearest representable value. The +assertion that FLT_ROUNDS has the value of 1 is an attempt to guarantee +this. You might check your float.h; if this isn't #defined as a constant 1 +you should investigate how to ensure that it will always round to the +nearest. If it is #defined as 1 you can safely rip out the assertions. The +addition of 2.0*(LONG_MAX+1.0) for the signed long is to prevent the the MSB +of the mantissa being borrowed for negative inputs - if this happened, the +exponent would change and the LSB of the mantissa would no longer be worth +1. This offset would be perfectly okay to use with the unsigned longs too +but it's unnecessary for them, unless you want to get the answer correct +modulo 2^^32 for negatives. + +*/ diff --git a/reference/C/CONTRIB/SNIP/dblround.c b/reference/C/CONTRIB/SNIP/dblround.c new file mode 100755 index 0000000..5870fda --- /dev/null +++ b/reference/C/CONTRIB/SNIP/dblround.c @@ -0,0 +1,35 @@ +/* +** DBLROUND.C - Rounds a double to the nearest whole number +** public domain by Ross Cottrell +*/ + +#include +#include +#include + +double round(double x) +{ + assert(1 == FLT_ROUNDS); + x += 1.0 / DBL_EPSILON; + return x - 1.0 / DBL_EPSILON; +} + +#ifdef TEST + +#include +#include + +void main(int argc, char *argv[]) +{ + double val; + char *dummy; + + while (--argc) + { + val = strtod((const char *)(*(++argv)), &dummy); + printf("round(%g) = ", val); + printf("%.12g\n", round(val)); + } +} + +#endif /* TEST */ diff --git a/reference/C/CONTRIB/SNIP/dd_struc.h b/reference/C/CONTRIB/SNIP/dd_struc.h new file mode 100755 index 0000000..cd46c2d --- /dev/null +++ b/reference/C/CONTRIB/SNIP/dd_struc.h @@ -0,0 +1,31 @@ +/* +** DosDate macros - access bitfield values from DOS file date & time +** for Borland C and C++ compilers by: Wayne Hamilton +*/ + +#define dd_yr(d) (((struct { unsigned day:5, mo:4, yr:7; } *) &d)->yr) +#define dd_mo(d) (((struct { unsigned day:5, mo:4, yr:7; } *) &d)->mo) +#define dd_day(d) (((struct { unsigned day:5, mo:4, yr:7; } *) &d)->day) +#define dd_hr(t) (((struct { unsigned sec:5, mn:6, hr:5; } *) &t)->hr) +#define dd_mn(t) (((struct { unsigned sec:5, mn:6, hr:5; } *) &t)->mn) +#define dd_sec(t) (((struct { unsigned sec:5, mn:6, hr:5; } *) &t)->sec) + +/* then: year = dd_yr(ffblk.ff_date); */ + +#ifdef TEST + +#include +#include + +main(int argc, char *argv[]) +{ + struct ffblk ff; + + findfirst(argv[0], &ff, 0xff); + printf("%s was saved on %d-%d-%d at %d:%02d:%02d\n", argv[0], + dd_mo(ff.ff_fdate), dd_day(ff.ff_fdate), dd_yr(ff.ff_fdate), + dd_hr(ff.ff_ftime), dd_mn(ff.ff_ftime), 2 * dd_sec(ff.ff_ftime)); + return 0; +} + +#endif diff --git a/reference/C/CONTRIB/SNIP/dirent.h b/reference/C/CONTRIB/SNIP/dirent.h new file mode 100755 index 0000000..0121e91 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/dirent.h @@ -0,0 +1,97 @@ +/* +** DIRENT.H - Posix compliant header +** +** Original Copyright 1988-1991 by Bob Stout as part of +** the MicroFirm Function Library (MFL) +** +** This subset version is functionally identical to the +** version originally published by the author in Tech Specialist +** magazine and is hereby donated to the public domain. +*/ + +#ifndef DIRENT_H +#define DIRENT_H + +#include /* For FILENAME_MAX */ +#include + +#ifndef OS2 + #if defined(__ZTC__) + #define DSTRUCT FIND /* ZTC++/SC++ */ + #define ATTRIBUTE attribute + #define NAME name + #define TIME time + #define DATE date + #define FSIZE size + #pragma pack(1) + #include + #elif defined(__TURBOC__) + #define DSTRUCT ffblk /* TC/C++ */ + #define ATTRIBUTE ff_attrib + #define NAME ff_name + #define TIME ff_ftime + #define DATE ff_fdate + #define FSIZE ff_fsize + #include + #else + #define DSTRUCT find_t /* Assume MSC/QC */ + #define ATTRIBUTE attrib + #define NAME name + #define TIME time + #define DATE date + #define FSIZE size + #pragma pack(1) + #include + #endif +#else /* OS/2 */ + #define INCL_DOSFILEMAN + #include + struct DSTRUCT { + BYTE reserved[21]; + BYTE ATTRIBUTE; + FTIME TIME; + FDATE DATE; + ULONG FSIZE; + CHAR NAME[13]; + }; +#endif + +#define FA_ANY 0xff +#undef FA_DIREC +#define FA_DIREC 0x10 + +/* +** Portable find first/next functions from RFIND1ST.C +*/ + +struct DSTRUCT *rfind_1st(char *, unsigned, struct DSTRUCT *); +struct DSTRUCT *rfind_nxt(struct DSTRUCT *); + +typedef struct +{ + int dd_fd; + unsigned dd_loc, + dd_size; + struct DSTRUCT dd_buf; + char dd_dirname[FILENAME_MAX]; +} DOS_DIR; + +DOS_DIR *opendir(char *); +int closedir(DOS_DIR *), + rewinddir(DOS_DIR *); +struct DSTRUCT *readdir(DOS_DIR *), + *seekdir(DOS_DIR *, int, int); +#define telldir(dd) dd->loc + +/* +** Other useful functions from DIRMASK.C and PATMAT.C +*/ + +int dirmask(struct DSTRUCT *,char *,char *,unsigned,unsigned); +int patmat(const char *, const char *); + +extern int DFerr; + +extern DOS_DIR _DIRS[]; + +#endif /* DIRENT_H */ diff --git a/reference/C/CONTRIB/SNIP/dirmask.c b/reference/C/CONTRIB/SNIP/dirmask.c new file mode 100755 index 0000000..9e11438 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/dirmask.c @@ -0,0 +1,73 @@ +/* +** DIRMASK.C - Complex pattern matching +** +** Original Copyright 1988-1991 by Bob Stout as part of +** the MicroFirm Function Library (MFL) +** +** This subset version is functionally identical to the +** version originally published by the author in Tech Specialist +** magazine and is hereby donated to the public domain. +*/ + +#include +#include +#include "dirent.h" + +int patmat(const char *, const char *); + +typedef enum {ERROR = -1, FALSE, TRUE} LOGICAL; +#define SUCCESS 0 + +/****************************************************************/ +/* */ +/* dirmask() */ +/* */ +/* Tests a directory entry for matching patterns. Tests both */ +/* file name and attributes. Tests for both inclusion specs */ +/* and exclusion specs. */ +/* */ +/* Parameters: 1 - Pointer to the directory entry's FIND */ +/* structure */ +/* 2 - Filename for inclusion matching, i.e. if */ +/* this spec matches the filename, we matched. */ +/* Use NULL to match anything. */ +/* 3 - Filename for exclusion matching, i.e. if */ +/* this spec matches the filename, we failed. */ +/* Use NULL to exclude nothing. */ +/* 4 - Attribute for inclusion mask. Use FA_ANY */ +/* to match anything). */ +/* 5 - Attribute for exclusion mask. Use zero to */ +/* exclude nothing). */ +/* */ +/* Returns: SUCCESS if name and attribute matched, else ERROR. */ +/* */ +/* Side effects: Converts patterns to upper case */ +/* */ +/****************************************************************/ + +int dirmask(struct DSTRUCT *dstruct, + char *fname_inc, + char *fname_exc, + unsigned attr_inc, + unsigned attr_exc) +{ + if (!dstruct) + return ERROR; + strupr(fname_inc); + strupr(fname_exc); + if (fname_inc) + { + if (TRUE != patmat(dstruct->NAME, fname_inc)) + return ERROR; + } + if (fname_exc) + { + if (TRUE == patmat(dstruct->NAME, fname_exc)) + return ERROR; + } + if (!((dstruct->ATTRIBUTE | 0x80) & attr_inc)) + return ERROR; + if (dstruct->ATTRIBUTE & attr_exc) + return ERROR; + return SUCCESS; +} diff --git a/reference/C/CONTRIB/SNIP/do.c b/reference/C/CONTRIB/SNIP/do.c new file mode 100755 index 0000000..67bf758 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/do.c @@ -0,0 +1,17 @@ +/* +** DO.C - a simple facility for specifying multiple commands +*/ + +#include +#include + +void main(int argc, char *argv[]) +{ + if (2 > argc) + { + puts("Usage: DO \"DOS command 1\" \"DOS command 2\" ..."); + return; + } + while (--argc) + system(*++argv); +} diff --git a/reference/C/CONTRIB/SNIP/doansi.h b/reference/C/CONTRIB/SNIP/doansi.h new file mode 100755 index 0000000..d91f4ef --- /dev/null +++ b/reference/C/CONTRIB/SNIP/doansi.h @@ -0,0 +1,33 @@ +/* +** DOANSI.H - Portable ANSI screen code interpreter +** +** From DRSK_105.LZH (ansi.c), hereby declared free for use for whatever +** purposes by author: Mark Kimes +*/ + +/* set maxx,maxy as desired */ +void set_screensize (int reservedlines); + +/* put character c at x,y using attr as attribute */ +void put_char (char c,char attr,int x,int y); + +/* position hardware cursor at x,y */ +void pos_hardcursor (int x,int y); + +/* turn hardware cursor off */ +void hardcursor_off (void); + +/* turn hardware cursor on at x,y */ +void hardcursor_on (int x,int y); + +/* scroll window tx,ty - bx,by up one line; fill with blank+attr */ +void scroll_up (int tx,int ty,int bx,int by,char attr); + +/* clear the window from tx,ty - bx,by; fill with blank+attr */ +void clearwindow (int tx,int ty,int bx,int by,char attr); + +/* clear line y from col x to eol (ex); fill with blank+attr */ +void cleartoeol (int x,int y,int ex,char attr); + +/* the ansi string interpreter */ +int ansi_out (char *buf); diff --git a/reference/C/CONTRIB/SNIP/doansi_1.c b/reference/C/CONTRIB/SNIP/doansi_1.c new file mode 100755 index 0000000..f328cb1 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/doansi_1.c @@ -0,0 +1,478 @@ +/* +** DOANSI_1.C - Portable ANSI screen code interpreter +** +** From DRSK_105.LZH (ansi.c), hereby declared free for use for whatever +** purposes by author: Mark Kimes +*/ + +#include +#include +#include +#include "doansi.h" + +/* + * to initialize: + * call set_screensize(<# lines to reserve>); + * to print through ansi interpreter: + * call ansi_out(); + */ + +char curattr = 7; +int curx = 0,cury = 0; +int maxx = 80, maxy = 25; /* size of ansi output window */ +int realmaxy,realmaxx; /* real screen size */ +char useansi = 1; /* while true, interp ansi seqs */ +int tabspaces = 8; +static int savx,savy,issaved = 0; +static char ansi_terminators[] = "HFABCDnsuJKmp"; + +#define MAXARGLEN 128 + +#define NOTHING 0 +#define WASESCAPE 1 +#define WASBRKT 2 + +/* "generic" support functions closely related to ansi_out */ + +void set_pos (char *argbuf,int arglen,char cmd) +{ + int y,x; + char *p; + + if (!*argbuf || !arglen) + { + curx = cury = 0; + } + y = atoi(argbuf) - 1; + p = strchr(argbuf,';'); + if (y >= 0 && p) + { + x = atoi(p + 1) - 1; + if(x >= 0) + { + curx = x; + cury = y; + } + } +} + +void go_up (char *argbuf,int arglen,char cmd) +{ + int x; + + x = atoi(argbuf); + if (!x) + x = 1; + for ( ; x ; x--) + { + if (!cury) + break; + cury--; + } +} + +void go_down (char *argbuf,int arglen,char cmd) +{ + int x; + + x = atoi(argbuf); + if (!x) + x = 1; + for ( ; x ; x--) + { + if (cury == maxy - 1) + break; + cury++; + } +} + +void go_left (char *argbuf,int arglen,char cmd) +{ + int x; + + x = atoi(argbuf); + if (!x) + x = 1; + for ( ; x ; x--) + { + if(!curx) + break; + curx--; + } +} + +void go_right (char *argbuf,int arglen,char cmd) +{ + int x; + + x = atoi(argbuf); + if (!x) + x = 1; + for ( ; x ; x--) + { + if (curx == maxx - 1) + break; + curx++; + } +} + +void report (char *argbuf,int arglen,char cmd) +{ + /* you figure out how to implement it ... */ +} + +void save_pos (char *argbuf,int arglen,char cmd) +{ + savx = curx; + savy = cury; + issaved = 1; +} + +void restore_pos (char *argbuf,int arglen,char cmd) +{ + if(issaved) + { + curx = savx; + cury = savy; + issaved = 0; + } +} + +void clear_screen (char *argbuf,int arglen,char cmd) +{ + /* needs error checking */ + + clearwindow(0,0,maxx - 1,maxy - 1,curattr); + curx = cury = 0; +} + +void kill_line (char *argbuf,int arglen,char cmd) +{ + cleartoeol(curx,cury,maxx - 1,curattr); +} + + +void set_colors (char *argbuf,int arglen,char cmd) +{ + char *p,*pp; + + if (*argbuf && arglen) + { + pp = argbuf; + do + { + p = strchr(pp,';'); + if (p && *p) + { + *p = 0; + p++; + } + switch (atoi(pp)) + { + case 0: /* all attributes off */ + curattr = 7; + break; + + case 1: /* bright on */ + curattr |= 8; + break; + + case 2: /* faint on */ + curattr &= (~8); + break; + + case 3: /* italic on */ + break; + + case 5: /* blink on */ + curattr |= 128; + break; + + case 6: /* rapid blink on */ + break; + + case 7: /* reverse video on */ + curattr = 112; + break; + + case 8: /* concealed on */ + curattr = 0; + break; + + case 30: /* black fg */ + curattr &= (~7); + break; + + case 31: /* red fg */ + curattr &= (~7); + curattr |= 4; + break; + + case 32: /* green fg */ + curattr &= (~7); + curattr |= 2; + break; + + case 33: /* yellow fg */ + curattr &= (~7); + curattr |= 6; + break; + + case 34: /* blue fg */ + curattr &= (~7); + curattr |= 1; + break; + + case 35: /* magenta fg */ + curattr &= (~7); + curattr |= 5; + break; + + case 36: /* cyan fg */ + curattr &= (~7); + curattr |= 3; + break; + + case 37: /* white fg */ + curattr |= 7; + break; + + case 40: /* black bg */ + curattr &= (~112); + break; + + case 41: /* red bg */ + curattr &= (~112); + curattr |= (4 << 4); + break; + + case 42: /* green bg */ + curattr &= (~112); + curattr |= (2 << 4); + break; + + case 43: /* yellow bg */ + curattr &= (~112); + curattr |= (6 << 4); + break; + + case 44: /* blue bg */ + curattr &= (~112); + curattr |= (1 << 4); + break; + + case 45: /* magenta bg */ + curattr &= (~112); + curattr |= (5 << 4); + break; + + case 46: /* cyan bg */ + curattr &= (~112); + curattr |= (3 << 4); + break; + + case 47: /* white bg */ + curattr |= 112; + break; + + case 48: /* subscript bg */ + break; + + case 49: /* superscript bg */ + break; + + default: /* unsupported */ + break; + } + pp = p; + } while (p); + } +} + +int ansi_out (char *buf) +{ + int arglen = 0, ansistate = NOTHING, x; + char *b = buf, argbuf[MAXARGLEN] = ""; + + /* cursor is off while string is being displayed so we don't have + to keep updating it. works to our detriment only if using + BIOS writes under MS-DOS + */ + + hardcursor_off(); + + if (!useansi) /* is ANSI interp on? */ + { + ansistate = NOTHING; + arglen = 0; + *argbuf = 0; + } + + while (*b) + { + switch (ansistate) + { + case NOTHING: + switch (*b) + { + case '\x1b': + if (useansi) + { + ansistate = WASESCAPE; + break; + } + + case '\r': + curx = 0; + break; + + case '\n': + cury++; + if (cury > maxy - 1) + { + scroll_up(0,0,maxx - 1,maxy - 1,curattr); + cury--; + } + break; + + case '\t': /* so _you_ figure out what to do... */ + for (x = 0; x < tabspaces; x++) + { + put_char(' ',curattr,curx,cury); + curx++; + if (curx > maxx - 1) + { + curx = 0; + cury++; + if (cury > maxy - 1) + { + scroll_up(0, 0, maxx - 1, maxy - 1, + curattr); + cury--; + } + } + } + break; + + case '\b': + if (curx) + { + curx--; + } + break; + + case '\07': /* usually a console bell */ + putchar('\07'); + break; + + default: + put_char(*b,curattr,curx,cury); + curx++; + if (curx > maxx - 1) + { + curx = 0; + cury++; + if (cury > maxy - 1) + { + scroll_up(0,0,maxx - 1,maxy - 1,curattr); + cury--; + } + } + break; + } + break; + + case WASESCAPE: + if (*b == '[') + { + ansistate = WASBRKT; + arglen = 0; + *argbuf = 0; + break; + } + ansistate = NOTHING; + break; + + case WASBRKT: + if (strchr(ansi_terminators, (int)*b)) + { + switch ((int)*b) + { + case 'H': /* set cursor position */ + case 'F': + set_pos(argbuf,arglen,*b); + break; + + case 'A': /* up */ + go_up(argbuf,arglen,*b); + break; + + case 'B': /* down */ + go_down(argbuf,arglen,*b); + break; + + case 'C': /* right */ + go_right(argbuf,arglen,*b); + break; + + case 'D': /* left */ + go_left(argbuf,arglen,*b); + break; + + case 'n': /* report pos */ + report(argbuf,arglen,*b); + break; + + case 's': /* save pos */ + save_pos(argbuf,arglen,*b); + break; + + case 'u': /* restore pos */ + restore_pos(argbuf,arglen,*b); + break; + + case 'J': /* clear screen */ + clear_screen(argbuf,arglen,*b); + break; + + case 'K': /* delete to eol */ + kill_line(argbuf,arglen,*b); + break; + + case 'm': /* set video attribs */ + set_colors(argbuf,arglen,*b); + break; + + case 'p': /* keyboard redef -- disallowed */ + break; + + default: /* unsupported */ + break; + } + ansistate = NOTHING; + arglen = 0; + *argbuf = 0; + } + else + { + if (arglen < MAXARGLEN) + { + argbuf[arglen] = *b; + argbuf[arglen + 1] = 0; + arglen++; + } + } + break; + + default: + pos_hardcursor(curx,cury); + fputs("\n **Error in ANSI state machine.\n",stderr); + break; + } + b++; + } + pos_hardcursor(curx,cury); + hardcursor_on(curx,cury); + + return ((int)b - (int)buf); +} diff --git a/reference/C/CONTRIB/SNIP/doansi_2.c b/reference/C/CONTRIB/SNIP/doansi_2.c new file mode 100755 index 0000000..b20fc3e --- /dev/null +++ b/reference/C/CONTRIB/SNIP/doansi_2.c @@ -0,0 +1,229 @@ +/* +** DOANSI_2.C - OS-Specific ANSI screen code interpreter functions +** +** From DRSK_105.LZH (ansi.c), hereby declared free for use for whatever +** purposes by author: Mark Kimes +*/ + +#ifdef OS2 + +#define INCL_DOS +#define INCL_VIO + +#include + +int vidhandle = 0; /* can be changed for AVIO */ + +void set_screensize (int reservedlines) +{ + VIOMODEINFO vm; + + vm.cb = sizeof(VIOMODEINFO); + VioGetMode(&vm, vidhandle); + maxx = vm.col; + maxy = vm.row - reservedlines; + realmaxx = maxx; + realmaxy = vm.row; +} + +void pos_hardcursor (int x,int y) +{ + VioSetCurPos(y,x,vidhandle); +} + +void hardcursor_off (void) +{ + VIOCURSORINFO vc; + + VioGetCurType(&vc,vidhandle); + vc.attr = -1; + VioSetCurType(&vc,vidhandle); +} + +void hardcursor_on (int x,int y) +{ + VIOCURSORINFO vc; + + VioGetCurType(&vc,vidhandle); + vc.attr = 0; + VioSetCurType(&vc,vidhandle); + VioSetCurPos(y,x,vidhandle); +} + +void put_char (char c, char attr, int x, int y) +{ + VioWrtCharStrAtt(&c,1,y,x,&attr,vidhandle); +} + +void scroll_up (int tx,int ty,int bx,int by,char attr) +{ + int attrib = ' ' | (attr << 8); + + VioScrollUp(ty,tx,by,bx,1,(char *)&attrib,vidhandle); +} + +void clearwindow (int tx,int ty,int bx,int by,char attr) +{ + int attrib = ' ' | (attr << 8); + + VioScrollUp(ty,tx,by,bx,-1,(char *)&attrib,vidhandle); +} + +void cleartoeol (int x,int y,int ex,char attr) +{ + int attrib = ' ' | (attr << 8); + + VioScrollUp(y,x,y,ex,-1,(char *)&attrib,vidhandle); +} + +#else + +/* MS-DOS -- (urp) */ + +#include + +#if !defined(MK_FP) + #define MK_FP(seg,off) ((void far *)(((long)(seg) << 16)|(unsigned)(off))) +#endif + +static int far *vseg; +int realmaxy,realmaxx; +char usebios = 0; /* if true, output through BIOS */ + +int vmode (void) +{ + union REGS r; + + r.h.ah = 15; + r.x.bx = 0; + int86(0x10,&r,&r); + return r.h.al; +} + +void set_screensize (int reservedlines) +{ + union REGS r; + unsigned int vbase; + + r.h.ah = 0x0f; + r.x.bx = 0; + int86 (0x10, &r, &r); + maxx = (int) r.h.ah; + if (maxx < 80) /* gimme a break! */ + { + r.x.ax = 0x0003; + int86(0x10,&r,&r); + maxx = 80; + } + realmaxx = maxx; + r.x.ax = 0x1130; + r.x.dx = maxy; + int86 (0x10, &r, &r); + realmaxy = maxy = (r.x.dx == 0) ? 25 : (r.x.dx + 1); + maxy -= reservedlines; + vbase = (vmode () == 7 ? 0xb000 : 0xb800); + vseg = MK_FP(vbase,0); /* address of video ram as pointer */ +} + +void pos_hardcursor (int x,int y) +{ + union REGS r; + + r.x.ax = 0x0200; + r.x.bx = 0; + r.x.dx = ((y << 8) & 0xff00) + x; + int86(0x10,&r,&r); +} + +void hardcursor_off (void) +{ + union REGS r; + + r.x.ax = 0x0200; + r.x.bx = 0; + r.x.dx = ((realmaxy << 8) & 0xff00); + int86(0x10,&r,&r); +} + +void hardcursor_on (int x,int y) +{ + union REGS r; + + r.x.ax = 0x0200; + r.x.bx = 0; + r.x.dx = ((y << 8) & 0xff00) + x; + int86(0x10,&r,&r); +} + +void put_char (char c, char attr, int x, int y) +{ + if(!usebios) + { + register int far *v; + + /* point v to right spot in vid RAM */ + + v = vseg + ((y * realmaxx) + x); + *v = (c | (attr << 8)); /* display */ + } + else + { + + union REGS r; + + r.x.ax = 0x0200; + r.x.bx = 0; + r.x.dx = ((y << 8) & 0xff00) + x; + int86(0x10,&r,&r); + r.h.ah = 0x09; + r.h.bh = 0; + r.h.bl = attr; + r.x.cx = 1; + r.h.al = c; + int86(0x10,&r,&r); + } +} + +void scroll_up (int tx,int ty,int bx,int by,char attr) +{ + union REGS r; + + r.h.ah = 6; + r.h.al = 1; + r.h.bh = attr; + r.h.cl = tx; + r.h.ch = ty; + r.h.dl = bx; + r.h.dh = by; + int86(0x10,&r,&r); +} + +void clearwindow (int tx,int ty,int bx,int by,char attr) +{ + union REGS r; + + r.h.ah = 6; + r.h.al = 0; + r.h.bh = attr; + r.h.cl = tx; + r.h.ch = ty; + r.h.dl = bx; + r.h.dh = by; + int86(0x10,&r,&r); +} + +void cleartoeol (int x,int y,int ex,char attr) +{ + union REGS r; + + r.h.ah = 6; + r.h.al = 0; + r.h.bh = attr; + r.h.cl = x; + r.h.ch = y; + r.h.dl = ex; + r.h.dh = y; + int86(0x10,&r,&r); +} + +#endif diff --git a/reference/C/CONTRIB/SNIP/dos5boot.h b/reference/C/CONTRIB/SNIP/dos5boot.h new file mode 100755 index 0000000..fccd398 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/dos5boot.h @@ -0,0 +1,40 @@ +/* +** DOS5BOOT.H - DOS 5 boot record +*/ + +#if defined(__TURBOC__) + #pragma option -a- + #define FAR far +#elif defined(__ZTC__) + #pragma ZTC align 1 + #define FAR _far +#else /* MSC/QC/WATCOM/METAWARE */ + #pragma pack(1) + #define FAR _far +#endif + +typedef struct { /* offset in buffer record */ + char bsJump[3]; /* 1 - 3 */ + char bsOemName[8]; /* 4 - 11 */ + short bsBytesPerSec; /* 12 - 13 */ + char bsSecPerClust; /* 14 */ + short bsResSectors; /* 15 - 16 */ + char bsFATs; /* 17 */ + short bsRootDirEnts; /* 18 - 19 */ + short bsSectors; /* 20 - 21 */ + char bsMedia; /* 22 */ + short bsFATsecs; /* 23 - 24 */ + short bsSecPerTrack; /* 25 - 26 */ + short bsHeads; /* 27 - 28 */ + long bsHiddenSecs; /* 29 - 32 */ + long bsHugeSectors; /* 33 - 36 */ + char bsDriveNumber; /* 37 */ + char bsReserved1; /* 38 */ + char bsBootSignature; /* 39 */ + long bsVolumeID; /* 40 - 43 */ + char bsVolumeLabel[11]; /* 44 - 54 */ + char bsFileSysType[8]; /* 54 - 61 */ + char bsReserved2[8]; /* 62 - 69 */ + char bsJunk[442]; /* 70 - end of record + (byte 512 is last) */ + } B_REC; /* Boot_record; total of 512 bytes */ diff --git a/reference/C/CONTRIB/SNIP/doscopy.c b/reference/C/CONTRIB/SNIP/doscopy.c new file mode 100755 index 0000000..2725c60 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/doscopy.c @@ -0,0 +1,58 @@ +/*************************************************** + * function : copy * + * purpose : copy one file * + * * + * arguments: path to source 'fromDir', * + * path to target 'toDir', * + * filename to copy 'fname' * + * * + * returns : nothing * + * * + * By : Peter Yard (29 May 1991) * + ***************************************************/ + +#include +#include +#include +#include + +void pmerge(char *path, char *drive, char *dir, char *fname, char *ext); + +#define STDOUT fileno(stdout) + +void copy(char *fromDir, char *fname, char *toDir) +{ + FILE *nul; /* nul will redirect stdout to DOS 'nul' */ + char from[FILENAME_MAX], to[FILENAME_MAX], comd[128]; + int bytesRead, oldStdout; + + /* Create the strings to describe the paths */ + + pmerge(from, NULL, fromDir, fname, NULL); + pmerge(to, NULL, toDir, fname, NULL); + + /* Construct 'comd' string which is a dos command for a copy */ + + strcpy(comd, "copy "); + strcat(comd, from); strcat(comd, " "); + strcat(comd, to); + + /* Redirect stdout to a nul file, kills output to the screen */ + + nul = fopen("NUL", "w"); + oldStdout = dup(STDOUT); + dup2(fileno(nul), STDOUT); + fclose(nul); + + system(comd); /* COPY file */ + + /* Restore stdout and close nul file */ + + dup2(oldStdout, STDOUT); + close(oldStdout); + + /* Display file source and target, */ + /* otherwise comment out the next line. */ + + printf("\n%s copied to %s",from,to); +} diff --git a/reference/C/CONTRIB/SNIP/dosfuncs.txt b/reference/C/CONTRIB/SNIP/dosfuncs.txt new file mode 100755 index 0000000..9b00d2f --- /dev/null +++ b/reference/C/CONTRIB/SNIP/dosfuncs.txt @@ -0,0 +1,34 @@ +The following SNIPPETS files are either MS/PC-DOS specific or have limited +application in other environments: + +Make.Ini Ansiscrn.H Dd_Struc.H Portable.H Scrnmacs.H +8087_Sav.Asm Coldboot.Asm Cpucheck.Asm Hires.Asm Ndpcheck.Asm +Strecpy.Asm Addhndls.C Addpath.C Ansiload.C Ansisys.C +Assignpr.C Atr2Ansi.C Break.C Changprn.C Checkexe.C +Chgext.C Clock.C Compiler.C Cursor.C Doscopy.C +Droptime.C Drvalid.C Drvs.C Dspdtst.C Faskbhit.C +Favail.C Files.C Fndislot.C Format.C Fsize.C +Getdcwd.C Getkey.C Getseg.C Glbl_Env.C Grafline.C +Hugeread.C Hugesort.C Iscons.C Isfopen.C Isnetdr.C +Isramdsk.C Isshift.C Iswprot.C Isxkbrd.C Joystick.C +Kb_Data.C Keylocks.C Keywatch.C Lsary.C Mcb_Env.C +Memavail.C Msb2Ieee.C Noctrlc.C Noreset.C Os_Id.H +Os_Id.C Pcnvrt.C Prtoggle.C Prtscrn.C Prtstat.C +Reboot.C Scroll.C Setenvar.C Shel2Dos.C Tp6Tod.C +Truename.C Unix2Dos.C Vfname.C Video.C Whicharc.C +Which_C.Txt Environ.Txt Evsavres.Txt Vio.H Vio.Asm +Scrnsave.C Int2E.Asm Ccomcall.C Dirent.H Rfind1St.C +Posixdir.C Posix_Ls.C Flnorm.C Uclock.H Uclock.C +Sound.H Sound.C Mktone.C Playlib.C Playdemo.C +X00Api.H X00Api.C Prnspool.H Prnspool.C Printq.C +Strat.H Strat.C Dos5Boot.H Absdiskc.C Absdisk.Asm +Mouse.H Mouse.C Scrnpick.C Ext_Keys.H Ext_Keys.C +Doansi.H Doansi_1.C Doansi_2.C Tasker.Txt Tasker.H +Tasker.C Biport.H Biport.C Fmemops.C Ftime.H +Ftime.C Msc_Peek.C Pmerge.C Psplit.C Vidport.C +Big_Mall.H Except.Doc Cctrap.Asm Cbtrap.Asm Trapflag.Asm +Trapdemo.C Cerrinst.Asm Cerrtrap.Asm Bordcolr.C Cdir.C +Chmod.C Cursize.C Do.C Drivsrch.C Dspclock.C +Filcount.C Flopcopy.C Getvol.C Kbflip.C Lsd.C +Mterm.C Rm_All.C Setimeto.C Setvol.C Stripeof.C +Todaybak.C Touch.C Treedir.C diff --git a/reference/C/CONTRIB/SNIP/dossort.c b/reference/C/CONTRIB/SNIP/dossort.c new file mode 100755 index 0000000..85f4392 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/dossort.c @@ -0,0 +1,118 @@ +/* + + cl /AL sortit.c + +=========================================================== + sort.c 7-31-91 Robert Mashlan + + This filter is almost compatible with the MS-DOS filter of the same name. + + This filter sorts each line of standard input, disregarding case, + and sends it to standard output. + + optional parameters: /R Output in reverse order + /+n Compare at column n, 1 based + + example usage: sort < unsorted.txt > sorted.txt + + note: compile in a far data model for maximum capacity ( compact or large ) + +*/ + +#include +#include +#include + +#define MAXLINES 10000 /* maximum number of lines to sort */ +#define MAXLINE 80 /* maximum line length */ + +unsigned col = 0; /* column to start sort at ( zero based here ) */ +int reverse = 0; /* reverse order flag */ + +/* +** compare function for qsort +*/ + +int cmp( const void *a, const void *b) +{ + int result; + const char *_a = *(const char **)a; + const char *_b = *(const char **)b; + + /* compare at col if other than zero */ + + if (col > 0) + { + if (strlen(_a) > col) + _a += col; + else _a = ""; + if (strlen(_b) > col) + _b += col; + else _b = ""; + } + result = stricmp(_a,_b); + return reverse ? -result : result; +} + +int main(int argc, char *argv[]) +{ + static char *lines[MAXLINES]; + int i, nlines=0, no_match; + char buf[MAXLINE]; + + /* scan for command line options */ + + for(i=1;i +#include + +#if !defined(MK_FP) + #define MK_FP(seg,off) ((void far *)(((long)(seg) << 16)|(unsigned)(off))) +#endif + +#ifdef __TURBOC__ + #define _far far +#endif + +void main(void) +{ + int i; + int unsigned result; + int drivestatus[26]; + unsigned char _far *DPB; + union REGS regs; + struct SREGS sregs; + + + /* routine checks for all valid drive possibilities from A to Z */ + + /* + ** if removeable media drive ie. floppy drive A: has a latch door + ** open you will get "Abort Retry" panic message + */ + + for (i = 0; i < 26; i++) + { + /* drive number (0=default, 1=A, 2=B,etc.)*/ + + regs.h.dl = (unsigned char)(i + 1); + segread(&sregs); + + regs.h.ah=0x32; /* DOS interrupt 32H */ + /* was undocumented for DOS release 3.2 */ + + intdosx(®s,®s, &sregs); + + result=regs.h.al; + DPB = MK_FP(sregs.ds, regs.x.bx); + + /* + ** result =0 then valid drive + ** =255 or ff hex then invalid or non-existent drive + */ + + if (0 == result && *DPB != (unsigned char)i) + drivestatus[i] = 1; + else drivestatus[i]=result; + } + + for (i = 0; i < 26; i = i + 2) + { + printf("drive %c: status code =%3d drive %c: status code =%3d\n", + 'A' + i,drivestatus[i],'B' + i,drivestatus[i+1]); + } + return; +} diff --git a/reference/C/CONTRIB/SNIP/droptime.c b/reference/C/CONTRIB/SNIP/droptime.c new file mode 100755 index 0000000..89406e9 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/droptime.c @@ -0,0 +1,21 @@ +/** int drop_time(void) +** +** Drops current timeslice in OS/2, Win, DPMI 1.0 and (I think) DV +** +** Returns: 0 if not successful, 1 if dropped +** +** Based on Ralf Brown's Interrupt list. +** Donated to Public Domain by Thor Johnson. +** +***********************************************************************/ + +#include + +int drop_time(void) /* Drops Time-slice, giving to another program */ +{ + union REGS regs; + + regs.x.ax = 0x1680; + int86(0x2f, ®s, ®s); + return (regs.h.al == 0x80)? 0 : 1; +} diff --git a/reference/C/CONTRIB/SNIP/drvalid.c b/reference/C/CONTRIB/SNIP/drvalid.c new file mode 100755 index 0000000..de0204a --- /dev/null +++ b/reference/C/CONTRIB/SNIP/drvalid.c @@ -0,0 +1,166 @@ +/* +** DRVALID.C - validate disk drives +** +** Original Copyright 1988-1991 by Bob Stout as part of +** the MicroFirm Function Library (MFL) +** +** This subset version is functionally identical to the +** version originally published by the author in Tech Specialist +** magazine and is hereby donated to the public domain. +** +** Uses ABSDISKC.C and ABSDISK.ASM in SNIPPETS. +*/ + +#include +#include + +typedef enum {ERROR = -1, SUCCESS, FALSE = 0, TRUE} LOGICAL; + +/* +** Function to read an absolute disk sector +*/ + +int AbsDiskRead(unsigned short, size_t, size_t, void *); + +/* +** getdrv() +** +** Just as getcwd() returns the default directory, getdrv() returns +** the current drive. +** +** Arguments: None. +** +** Returns: Current drive (0 = A:, 1 = B:, etc.) +** +** Side effects: none +*/ + +int getdrv(void) +{ + union REGS regs; + + regs.h.ah = 0x19; + intdos(®s, ®s); + return (regs.h.al); +} + +/* +** chdrv() +** +** Like chdir(), except changes drives rather than directories. +** +** Arguments: 1 - target drive (0 = A:, 1 = B:, etc.) +** +** Returns: SUCCESS or ERROR +** +** Side effects: none +*/ + +LOGICAL chdrv(int drive) +{ + union REGS regs; + + regs.h.ah = 0x0e; + regs.h.dl = (char)drive; + intdos(®s, ®s); + if (drive != getdrv()) + return ERROR; + else return SUCCESS; +} + +/* +** drvalid() +** +** Verifies whether a logical disk drive is available without +** triggering the DOS critical error handler. +** +** Arguments: 1 - target drive (0 = A;, 1 = B:, etc.) +** +** Returns: TRUE - drive is valid +** FALSE - drive is invalid +** +** Side effects: none +*/ + +LOGICAL drvalid(int drive) +{ + int original, result; + + original = getdrv(); + result = (SUCCESS == chdrv(drive)); + chdrv(original); + return result; +} + +/* +** drvrdy() +** +** Checks whether a drive with removable media is ready. +** +** Arguments: 1 - target drive (0 = A;, 1 = B:, etc.) +** +** Returns: TRUE - drive is ready +** FALSE - drive is not ready +** ERROR - other read error +** +** Side effects: none +*/ + +LOGICAL drvrdy(int drive) +{ + int status; + char buf[2048]; /* nice & roomy */ + + status = AbsDiskRead(drive, 1, 0, buf); + if (0 == status) + return TRUE; + status &= 0xff; + if (2 == status) + return FALSE; + else return ERROR; +} + +#ifdef TEST + +#include +#include + +int main(int argc, char *argv[]) +{ + int drive; + + if (2 > argc) + { + puts("Usage: DRVALID drive[:]"); + return EXIT_FAILURE; + } + drive = toupper(*argv[1]); + if (!isalpha(drive)) + { + puts("Error: Invalid drive name"); + return EXIT_FAILURE; + } + printf("Drive %c: is %svalid\n", drive, + drvalid(drive - 'A') ? "" : "not "); + if (2 < _osmajor) + { + union REGS regs; + + regs.x.ax = 0x4408; + regs.h.bl = (unsigned char)(drive - '@'); + intdos(®s, ®s); + printf("ioctl returned Cflag=%s\n", + regs.x.cflag ? "TRUE" : "FALSE"); + printf("ioctl returned AX=0x%X\n", regs.x.ax); + printf("Drive %c is%s removable\n", drive, + regs.x.ax ? " not" : ""); + if (0 == regs.x.ax) + { + printf("Drive %c is %sready\n", drive, + drvrdy(drive - 'A') ? "" : "not "); + } + } + return EXIT_SUCCESS; +} + +#endif /* TEST */ diff --git a/reference/C/CONTRIB/SNIP/drvs.c b/reference/C/CONTRIB/SNIP/drvs.c new file mode 100755 index 0000000..2002d8c --- /dev/null +++ b/reference/C/CONTRIB/SNIP/drvs.c @@ -0,0 +1,43 @@ +/* +** DRVS.C - public domain by David Gersic, DeKalb, Il 1993 +** +** Routine checks how many valid disk drives are available on machine, +** both physical and logical drives. +** +** Includes drive letters assigned with DOS SUBST command and network +** drives for Novell Netware (and probably other networks). +** +** Compiled Under MSC 6 LARGE memory Model +** Should be compatible with other DOS compilers +** +*/ + +#include +#include +#include + +main() +{ + union REGS in, out; + int i; + + /* Novell's shell TSRs allow up to 32 drive 'letters' to be created */ + + char drives[]={' ','a','b','c','d','e','f','g','h','i','j', + 'k','l','m','n','o','p','q','r','s','t','u', + 'v','w','x','y','z','[','\\',']','^','_','`'}; + + in.x.ax=0x4409; /* IOCTL function - Check if block device remote */ + for(i = 1; i < 32; i++) + { + in.h.bl=(unsigned char)i; /* 1==a:, 2==b:, etc. */ + intdos(&in,&out); + if(!out.x.cflag) /* carry flag set on error */ + { /* bit 15 == subst, bit 12 == 'remote'*/ + printf("drive %c: is %s\n", + drives[i],out.x.dx & 1<<15 ? "subst" : + out.x.dx & 1<<12 ? "network" : "local"); + } + } + return(0); +} diff --git a/reference/C/CONTRIB/SNIP/dspclock.c b/reference/C/CONTRIB/SNIP/dspclock.c new file mode 100755 index 0000000..dad4329 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/dspclock.c @@ -0,0 +1,83 @@ +// public domain TSR clock code. By Michelangelo Jones, 1:141/575 or +// 1:1/124. Very little support available; this is a quick hack, not +// an example of the best way to write a clock TSR! Use at own risk. +// Runs under TC++/BC++. Your mileage may vary. + +#ifndef __HUGE__ +#error "Must be compiled using HUGE model-- for now" +#endif + +#include + +extern unsigned _heaplen = 0; +extern unsigned _stklen = 512; + +static char * screenbase = + (char *) MK_FP (0xb800, 0); // change for mono +static const long int * volatile ticks = // to 0xb000, 0 + (long int * volatile) MK_FP (0, 0x046c); + +int calls, lastsec, lastmin, lasthr; +const double tps = 18.20648; // found by experimentation! + +void interrupt (*oldhandler)(void); + +void displayclock (void) +{ + char *moveinto = screenbase + 300; + char *initwith = " : : "; + +// NOTE: This initializer only works because the attribute I want for the +// clock HAPPENS to be the same as the ASCII value for the SPACE char! +// Modify every alternate character if you want some other attribute. + + while (*initwith) + *moveinto++ = *initwith++; + lastsec = -1; + lastmin = -1; + lasthr = -1; + calls = 20; +} + +void interrupt clockproc(void) +{ + static long seconds; + + if (calls < 17) + calls++; + else + { + seconds = (long) ((double) *ticks / tps); + if (screenbase[301] != ' ') // if the attribute has changed, + displayclock(); // the screen scrolled, so update. + if (seconds % 60 != lastsec) + { + lastsec = seconds % 60; + calls = 0; + screenbase[314] = (char) (lastsec/10) + 48; + screenbase[316] = (char) (lastsec%10) + 48; + if ((! lastsec) || (lastmin < 0)) + { + lastmin = (seconds % 3600) / 60; + screenbase[308] = (char) (lastmin/10) + 48; + screenbase[310] = (char) (lastmin%10) + 48; + if ((! lastmin) || (lasthr < 0)) + { + lasthr = ((seconds % 86400L) / 3600L); + screenbase[302] = (char) (lasthr/10) + 48; + screenbase[304] = (char) (lasthr%10) + 48; + } + } + } + } + oldhandler (); +} + +void main(void) + +{ + oldhandler = getvect (0x1c); + displayclock(); + setvect (0x1c, clockproc); + keep (0, (_SS + (_SP/16) - _psp)); +} diff --git a/reference/C/CONTRIB/SNIP/dspdtst.c b/reference/C/CONTRIB/SNIP/dspdtst.c new file mode 100755 index 0000000..3646eba --- /dev/null +++ b/reference/C/CONTRIB/SNIP/dspdtst.c @@ -0,0 +1,149 @@ +/* +** Compiler I/O benchmarks +** public domain by Dave Knapp & Bob Stout +*/ + +#include +#include +#include + +typedef unsigned long dword; + +#ifdef M_I86 /* Identifier for MSC, QC, Watcom, or ZTC */ + + #ifndef __ZTC__ + #include + + #ifndef __WATCOMC__ + #ifdef _MSC_VER + #define LOGFILE "dspdtst.msc" + #else + #define LOGFILE "dspdtst.qc" + #endif + +// #define MK_FP(seg,off) ((void far *)(((dword)(seg)<<16)|(off))) + #else + #define LOGFILE "dspdtst.wc" + #endif /* not Watcom */ + + #define cputs(s) _outtext((char _far *)(s)) + #define gotoxy(col,row) _settextposition(row,col) + + #else /* if ZTC */ + + #include + + #define cputs(s) disp_puts(s "\n") + #define cprintf(s) disp_printf(s "\n") + #ifdef __SC__ + #define LOGFILE "dspdtst.sc" + #define gotoxy(col,row) __emit__(0xb2,col-1,0xb6,row-1,0xb7,0,0xb4,2,0xcd,0x10) + #else + #define LOGFILE "dspdtst.ztc" + #define gotoxy(col,row) asm(0xb2,col-1,0xb6,row-1,0xb7,0,0xb4,2,0xcd,0x10) + #endif + + #endif /* if ZTC */ +#else + #ifdef __BORLANDC__ + #define LOGFILE "dspdtst.bc" + #else + #define LOGFILE "dspdtst.tc" + #endif +#endif /* if TC */ + +dword far *bios_time = (dword far *)(0x0040006c); +dword time1,time2,time3,time4,time5,time6; + +void main(void) +{ + int i; + FILE *log = stdout, *nulfile; + +#ifdef __ZTC__ + disp_open(); +#endif + nulfile = fopen("NUL", "w"); + time1 = *bios_time; + for(i = 1; i < 1000; i++) + { + gotoxy(10,5); + puts("puts test."); + puts("this is the second line.\n"); + } + time1 = *bios_time - time1; + time2 = *bios_time; + for(i = 1; i < 1000; i++) + { + gotoxy(10,5); + printf("printf test.\n"); + printf("this is the second line.\n"); + } + time2 = *bios_time - time2; + time3 = *bios_time; + for(i = 1; i < 1000; i++) + { +#ifdef __ZTC__ + disp_move(4,9); + cputs("d_puts test."); +#else + gotoxy(10,5); + #if defined(M_I86) && !defined(__WATCOMC__) + cputs("_outtext test.\r\n"); + #else + cputs("cputs test.\r\n"); + #endif +#endif + cputs("this is the second line."); + } + time3 = *bios_time - time3; + time4 = *bios_time; + for(i = 1; i < 1000; i++) + { +#ifdef __ZTC__ + disp_move(4,9); + cprintf("d_printf test."); +#else + gotoxy(10,5); + cprintf("cprintf test.\r\n"); +#endif + cprintf("this is the second line."); + } + time4 = *bios_time - time4; + time5 = *bios_time; + for(i = 1; i < 1000; i++) + { + fputs("fputs test.\n", nulfile); + fputs("this is the second line.\n", nulfile); + } + time5 = *bios_time - time5; + time6 = *bios_time; + for(i = 1; i < 1000; i++) + { + fprintf(nulfile, "fprintf test.\n"); + fprintf(nulfile, "this is the second line.\n"); + } + time6 = *bios_time - time6; + +#ifdef __ZTC__ + disp_close(); +#endif + log = fopen(LOGFILE, "w"); + fputs("Times for 1000 iterations:\n\n", log); + fprintf(log, "puts %10.3f seconds\n", (double)time1 * .054945); + fprintf(log, "printf %10.3f seconds\n", (double)time2 * .054945); +#ifndef __ZTC__ + #if defined(M_I86) && !defined(__WATCOMC__) + fprintf(log, "_outtext %10.3f seconds\n", (double)time3 * .054945); + #else + fprintf(log, "cputs %10.3f seconds\n", (double)time3 * .054945); + #endif + fprintf(log, "cprintf %10.3f seconds\n", (double)time4 * .054945); +#else + fprintf(log, "d_puts %10.3f seconds\n", (double)time3 * .054945); + fprintf(log, "d_printf %10.3f seconds\n", (double)time4 * .054945); +#endif + fprintf(log, "fputs %10.3f seconds\n", (double)time5 * .054945); + fprintf(log, "fprintf %10.3f seconds\n", (double)time6 * .054945); + fclose(log); +} diff --git a/reference/C/CONTRIB/SNIP/editgets.c b/reference/C/CONTRIB/SNIP/editgets.c new file mode 100755 index 0000000..1ae1b74 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/editgets.c @@ -0,0 +1,371 @@ +/* editgets.c - line input w/editing */ +/* this code is released to the public domain */ +/* written by Jon Burchmore */ +/* modifications & enhancements by Bob Stout */ + +/* This is as close to ANSI compliant C that I could come, but it was made */ +/* on an IBM compatable computer, so I designed it for that platform. */ +/* If you're porting it to another computer type, please note how the IBM */ +/* passes enhanced keys. First, it sends an ASCIIZ (character 0), then a */ +/* standard character. Anyway, what the switch() statement does is check */ +/* to see if there WAS a zero sent, and if there wasn't, it just "falls" */ +/* through to the default, which handles normal characters. */ + +/* The conio header file provides the getch() function, which returns a */ +/* single character from the KEYBOARD, not stdin, and waits if it must. */ +/* It is be possible to re-write this function for a computer besides an */ +/* IBM PC. */ + +/* It would be possible to check the variable insert, and if it's on, make */ +/* the cursor large, and if it's off, make the cursor small, but my primary */ +/* goal is portability, not fancy add-ons */ + +/* Pardon the lack of comments. I'm a coder, not an author. Besides, if */ +/* you can't understand this, DON'T USE IT! (Words to live by) */ + +#include +#include +#include +#include + +#undef min +#define min(x,y) (((x) <= (y)) ? (x) : (y)) + +#define NUL 0x00 +#define ESC 0x1B +#define LEFT 0x4B +#define RIGHT 0x4D +#define HOME 0x47 +#define END 0x4F +#define INSERT 0x52 +#define DELETE 0x53 +#define BACKSPC 0x08 +#define ENTER 0x0D +#define CTLEND 0x75 +#define CTLHOME 0x77 +#define CTLRT 0x74 +#define CTLLFT 0x73 + +/* +** Password mode - '*' is echoed for all characters, only ESC, ENTER, +** BACKSPC, and CTLHOME are active. +*/ + +int password_mode = 0; + +/* +** Aruments: 1) Buffer to receive string +** 2) Size of buffer +** 3) Default string +*/ + +int jgets(char *s, int maxlen, char *string) +{ + char temp[500]; + int insert = 1, done = 0, pos, len, i, j, c, zeroflag; + + if (NULL == string) + string = ""; + + if (0 != (pos = len = strlen(string))) + strncpy(temp, string, min(len, maxlen)); + + for (i = 0; i < maxlen; ++i) + { + if (NUL == *string) + putchar('_'); + else putchar(*string++); + } + for (i = 0; i < (maxlen - len); ++i) + putchar(BACKSPC); + + while (!done) + { + zeroflag = 0; + if ((c = getch()) == 0) + { + zeroflag = 1; + c = getch(); + } + switch (c) + { + case ESC : + if (len == 0) + break; + if (pos != len) + { + for (i = pos; i < len; i++) + putch('_'); + for (i = len; i >= 0; i--) + { + putch(BACKSPC); + putch('_'); + putch(BACKSPC); + } + pos = len = 0; + break; + } + + case LEFT : + if (zeroflag) + { + if (password_mode) + break; + if (pos == 0) + break; + pos--; + putch(BACKSPC); + break; + } + + case RIGHT : + if (zeroflag) + { + if (password_mode) + break; + if (pos == len) + break; + if (pos != maxlen) + { + putch(temp[pos]); + pos++; + } + break; + } + + case HOME : + if (zeroflag) + { + if (password_mode) + break; + while (pos-- > 0) + putch(BACKSPC); + pos = 0; + break; + } + + case END : + if (zeroflag) + { + if (password_mode) + break; + while (pos < len) + putch(temp[pos++]); + break; + } + + case INSERT : + if (zeroflag) + { + if (password_mode) + break; + insert = (!(insert)); + break; + } + + case DELETE : + if (zeroflag) + { + if (password_mode) + break; + if (pos == len) + break; + for (i = pos; i < len; i++) + temp[i] = temp[i + 1]; + len--; + for (i = pos; i < len; i++) + putch(temp[i]); + putch('_'); + for (i = len + 1; i > pos; i--) + putch(BACKSPC); + break; + } + + case BACKSPC : + if (c == BACKSPC) + { + if (pos == 0) + break; + if (pos != len) + { + for (i = pos - 1; i < len; i++) + temp[i] = temp[i + 1]; + pos--; + len--; + putch(BACKSPC); + for (i = pos; i < len; i++) + putch(temp[i]); + putch('_'); + for (i = len; i >= pos; i--) + putch(BACKSPC); + } + else + { + putch(BACKSPC); + putch('_'); + putch(BACKSPC); + pos = --len; + } + break; + } + + case ENTER : + if (c == ENTER) + { + done = 1; + break; + } + + case CTLEND : + if (zeroflag) + { + if (password_mode) + break; + for (i = pos; i < len; ++i) + putch('_'); + for (i = pos; i < len; ++i) + putch(BACKSPC); + len = pos; + break; + } + + case CTLHOME : + if (zeroflag) + { + if (pos == 0) + break; + if (pos != len) + { + while (0 != pos) + { + for (i = pos - 1; i < len; i++) + temp[i] = temp[i + 1]; + pos--; + len--; + putch(BACKSPC); + for (i = pos; i < len; i++) + putch(temp[i]); + putch('_'); + for (i = len; i >= pos; i--) + putch(BACKSPC); + } + } + else + { + while (0 != pos) + { + putch(BACKSPC); + putch('_'); + putch(BACKSPC); + pos = --len; + } + } + break; + } + + case CTLRT : + if (zeroflag) + { + if (password_mode) + break; + do + { + if (pos == len) + break; + if (pos != maxlen) + { + putch(temp[pos]); + pos++; + } + } while (isspace(temp[pos])); + do + { + if (pos == len) + break; + if (pos != maxlen) + { + putch(temp[pos]); + pos++; + } + } while (!isspace(temp[pos])); + break; + } + + case CTLLFT : + if (zeroflag) + { + if (password_mode) + break; + do + { + if (pos == 0) + break; + pos--; + putch(BACKSPC); + } while (isspace(temp[pos])); + do + { + if (pos == 0) + break; + pos--; + putch(BACKSPC); + } while (!isspace(temp[pos])); + break; + } + + default : + if (zeroflag) + break; + if (c == 0 || pos == maxlen) + break; + if ((!(insert)) || pos == len) + { + temp[pos++] = (char)c; + if (pos > len) len++; + if (password_mode) + putch('*'); + else putch(c); + } + else + { + if (len == maxlen) + break; + for (i = len++; i >= pos; i--) + temp[i + 1] = temp[i]; + temp[pos++] = (char)c; + if (password_mode) + putch('*'); + else putch(c); + for (i = pos; i < len; i++) + putch(temp[i]); + for (i = len; i > pos; i--) + putch(BACKSPC); + } + } + } + temp[len] = '\0'; + strcpy(s, temp); + return len; +} + +#ifdef TEST + +void main(void) +{ + char mystring[60]; + + memset(mystring, 0, 60); + fputs("Enter any string: ", stdout); + jgets(mystring, 60, "This is a test"); + puts(""); + printf("editgets() returned:\n%s\n", mystring); + + password_mode = 1; + memset(mystring, 0, 60); + fputs("Enter any password: ", stdout); + jgets(mystring, 50, NULL); + puts(""); + printf("editgets() returned:\n%s\n", mystring); +} + +#endif diff --git a/reference/C/CONTRIB/SNIP/eng.c b/reference/C/CONTRIB/SNIP/eng.c new file mode 100755 index 0000000..ad8cf91 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/eng.c @@ -0,0 +1,50 @@ +/* ENG.C - Format floating point in engineering notation */ +/* Released to public domain by author, David Harmon, Jan. 1994 */ + +#include + +char *eng(double value, int places) +{ + const char * const prefixes[] = { + "a", "f", "p", "n", "æ", "m", "", "k", "M", "G", "T" + }; + int p = 6; + static char result[30]; + char *res = result; + + if (value < 0.) + { + *res++ = '-'; + value = -value; + } + while (value != 0 && value < 1. && p > 0) + { + value *= 1000.; + p--; + } + while (value != 0 && value > 1000. && p < 10 ) + { + value /= 1000.; + p++; + } + if (value > 100.) + places--; + if (value > 10.) + places--; + sprintf(res, "%.*f %s", places-1, value, prefixes[p]); + return result; +} + +#ifdef TEST + +#include + +main() +{ + double w; + + for (w = 1e-19; w < 1e16; w *= 42) + printf(" %g W = %sW\n", w, eng(w, 3)); + return 0; +} +#endif diff --git a/reference/C/CONTRIB/SNIP/enums.txt b/reference/C/CONTRIB/SNIP/enums.txt new file mode 100755 index 0000000..ae88298 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/enums.txt @@ -0,0 +1,55 @@ +Some of my favorites... +----------------------- + +typedef enum {ERROR = -1, SUCCESS, FALSE = 0, TRUE} logical; +#define BOOL(x) (!(!(x))) /* always TRUE or FALSE */ + +/* (trivial) Example code follows */ + +#define MAX_VAL 10000 /* data upper bound */ +#define MIN_VAL -37 /* data lower bound */ + +logical testfunc(int intvalue) +{ + if (MAX_VAL < intvalue || MIN_VAL > intvalue) + return ERROR; /* if out of bounds */ + else return BOOL(intvalue); /* zero returns FALSE, + anything else is TRUE*/ +} + +/* Examples using SUCCESS/ERROR */ + + if (SUCCESS == strcmp(my_string, "something")) + do_something(); + if (ERROR == open("my_file", O_READ)) + abort(); + + And, speaking of enumerated data types (which we can feel free to do +since they're now "official" with the adoption of ANSI C), these are very +handy when defining lists of data which may need to be appended in the +future. If you define your enums this way: + +enum CARS {CARS_MIN = -1, FORD, CHEVY, PLYMOUTH, CARS_MAX}; + +...then you can write "expandable" code as follows: + +logical real_car(enum CARS my_car) +{ + if (CARS_MIN >= my_car || CARS_MAX <= my_car) + return FALSE; + else return TRUE; +} + +By including `CARS_MIN' and `CARS_MAX' as dummy enumerations, you can +change the declaration to: + +enum CARS {CARS_MIN = -1, FORD, CHEVY, PLYMOUTH, FERRARI, CARS_MAX}; + +...and all your existing code will still work properly, allowing you to +spend your time writing new code to support the new enumerations rather +than going back to fix any bounds checking you may have already written. +In addition if, within the enum declaration, you declare `CARS_MIN = -1', +then you can also include this handy little bit of expandable code: + + printf("Right now, I know about %d type%s of CARS\n", CARS_MAX, + &"s"[1 == CARS_MAX]); diff --git a/reference/C/CONTRIB/SNIP/environ.txt b/reference/C/CONTRIB/SNIP/environ.txt new file mode 100755 index 0000000..4c1862d --- /dev/null +++ b/reference/C/CONTRIB/SNIP/environ.txt @@ -0,0 +1,63 @@ +Q. Why was only the DOS batch file and "Stuff-key-buffer method" + (SETENVAR.C) included in the original SNIPPETS? + + +A. The reason that I only included the "batch&stuff" method in my SNIPPETS + collection is simply that it's the *only* method you can rely on if your + program is going to be distributed. Quite simply, there is *NO* safe, + documented way under DOS to set an environment variable in the master + environment block - period! By back-tracking PSPs or MCBs, you can try + to locate the master environment and change it. You can also try to use + Int 2Eh, the command processor's "back door". But all of these methods + suffer from several shortcomings: + +1) Someone using the program might be using 4DOS, COMMAND PLUS, or some other + COMMAND.COM replacement. These don't always do things the same way as + COMMAND.COM and the diferences can cause you to crash, roll, & burn! For + example, several COMMAND.COM replacements allow the master environment + block to be located in extended, expanded, or high memory. In such a case, + backtracking PSPs or MCBs is less than useless, they're guranteed to + yield undefined errors. + +2) Int 2Eh seems to be the most universally supported, but cannot be used in + a program invoked from a batch file. The book, "Undocumented DOS" details + some procedures for making an Int 2Eh call safer but, again, these + techniques rely on implementation features of COMMAND.COM which might not + be available in alternate command processors. + +3) Even if everything else is safe, you still need a way of error trapping in + case your new environment variable might overwrite the end of the + available master envirnment block. This error trapping in inherent in + COMMAND.COM and alternate command processors (one reason why using the + Int 2Eh back door is potentially the safest way to try), but if you try to + modify things manually, you're on your own. If you do overwrite the end of + the master environment block, you'll have automatically corrupted your MCB + chain and possibly set yourself up for some *really* nasty surprises! + +4) Finally, there's the very fundamental question of which environment block + really is the master? Say you're in your comm program and hit the "shell + to DOS" key. A secondary copy of the command processor, be it COMMAND.COM + or whatever, is spawned and you're off and running. If you now run your + program from this secondary DOS shell, is its environment block the master + or is it the one from which you ran your comm program? Worse yet, + depending on how you set up CONFIG.SYS, the secondary shell may have a + considerably smaller environment block than the original. Despite having + set the "/E:" switch, your secondary shell will likely only have an + environment block whose size is equal to the current block size rounded + up to the next paragraph boundry. If you trace PSPs, you'll find the + secondary shell which you stand a good chance of over-running due to the + difference in the block size. If you trace MCBs, you'll find the real + master block, but then your changes will have disappered when you return + to your comm program, defeating the purpose of your program in the first + place. + + The inability to alter a parent program's environment block isn't a DOS + exclusive, BTW - it's an inheritance from Unix where the same limitation + applies. + + Finally, SNIPPETS now includes several of these alternate unsafe ways of + setting the master environment. INT2E.ASM & CCOMCALL.C together provide + access to the DOS command processor back door, GLBL_ENV.C provides means + for TC/TC++/BC++ and MSC/QC programmers to modify the master environment + by backtracking PSP pointers, and MCB_ENV.C serves the same purpose only + using the MCB tracking method. diff --git a/reference/C/CONTRIB/SNIP/errfix.c b/reference/C/CONTRIB/SNIP/errfix.c new file mode 100755 index 0000000..05fdc39 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/errfix.c @@ -0,0 +1,52 @@ +/* +** ERRFIX.C - redirect stderr to some other file under MS-DOS +** +** by Bob Jarvis +*/ + +#include +#include +#include +#include + +char *usage = "ERRFIX [filename] [prog] { {parm1} {parm2} ... {parmN} }\n" + " Redirects stderr to another file, then invokes a program\n" + " which will inherit the new definition of stderr.\n\n" + "Parameters:\n" + " filename (required) - the name of the file stderr should\n" + " be redirected to. Output written to stderr will\n" + " be routed to this file instead of the console.\n" + " prog (required) - name of the program to be run.\n" + " parm1...parmN (optional) - command-line parameters needed\n" + " to run the program specified by the 'prog' argument."; + +int main(int argc, char *argv[]) +{ + char **args = argv; + + if (3 > argc) + { + printf(usage); + return 1; + } + + if (NULL != argv[argc]) /* may be a problem under some compilers */ + { + args = malloc((argc+1) * sizeof(char *)); + if (NULL == args) + { + printf("Unable to allocate storage"); + return 2; + } + + memcpy(args, argv, argc * sizeof(char *)); + + args[argc] = NULL; + } + + freopen(args[1], "w", stderr); + + spawnvp(0, args[2], &args[2]); + + return 0; +} diff --git a/reference/C/CONTRIB/SNIP/eval.c b/reference/C/CONTRIB/SNIP/eval.c new file mode 100755 index 0000000..5829724 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/eval.c @@ -0,0 +1,314 @@ +/* +** EVAL.C - A simple mathematical expression evaluator in C +** +** operators supported: ( +** ) +** + +** - +** * +** / +** ^ +** +** limitations: 1 - No precedence rules are implemented. +** 2 - Numbers can be negated (e.g. "-13"), but not +** expressions (e.g. "-(13)"). +** +** Original Copyright 1991 by Bob Stout as part of +** the MicroFirm Function Library (MFL) +** +** This subset* version is hereby donated to the public domain. +** +** *(The MFL version adds 150 lines of code, 5 level precedence, +** logarithmic and transcendental operators, pi as a constant, +** named variables, and fully understands negation.) +*/ + +#include +#include +#include +#include +#include + +#define NUL '\0' + +typedef enum {R_ERROR = -2 /* range */, ERROR /* syntax */, SUCCESS} STATUS; + +static char delims[] = "+-*/^)("; /* Tokens */ +static char op_stack[256]; /* Operator stack */ +static double arg_stack[256]; /* Argument stack */ +static char token[256]; /* Token buffer */ +static int op_sptr, /* op_stack pointer */ + arg_sptr, /* arg_stack pointer */ + parens, /* Nesting level */ + state = 0; /* 0 = Awaiting expression + 1 = Awaiting operator + */ + +int evaluate(char *, double *); + +static int do_op(void); +static int do_paren(void); +static void push_op(char); +static void push_arg(double); +static STATUS pop_arg(double *); +static STATUS pop_op(int *); +static char *getexp(char *); +static char *getop(char *); +static void pack(char *); + +#ifdef TEST + +void main(int argc, char *argv[]) +{ + double val; + + printf("evaluate(%s) ", argv[1]); + printf("returned %d\n", evaluate(argv[1], &val)); + printf("val = %f\n", val); +} + +#endif + +/* +** Evaluate a mathematical expression +*/ + +int evaluate(char *line, double *val) +{ + double arg; + char *ptr = line, *str, *endptr; + int ercode; + + pack(line); + + while (*ptr) + { + switch (state) + { + case 0: + if (NULL != (str = getexp(ptr))) + { + if ('(' == *str) + { + push_op(*str); + ptr += strlen(str); + break; + } + + if (0.0 == (arg = strtod(str, &endptr)) && + NULL == strchr(str, '0')) + { + return ERROR; + } + push_arg(arg); + ptr += strlen(str); + } + else return ERROR; + + state = 1; + break; + + case 1: + if (NULL == (str = getop(ptr))) + return ERROR; + + if (strchr(delims, *str)) + { + if (')' == *str) + { + if (SUCCESS > (ercode = do_paren())) + return ercode; + } + else + { + push_op(*str); + state = 0; + } + + ptr += strlen(str); + } + else return ERROR; + + break; + } + } + + while (1 < arg_sptr) + { + if (SUCCESS > (ercode = do_op())) + return ercode; + } + if (!op_sptr) + return pop_arg(val); + else return ERROR; +} + +/* +** Evaluate stacked arguments and operands +*/ + +static int do_op(void) +{ + double arg1, arg2; + int op; + + if (ERROR == pop_op(&op)) + return ERROR; + + pop_arg(&arg1); + pop_arg(&arg2); + + switch (op) + { + case '+': + push_arg(arg2 + arg1); + break; + + case '-': + push_arg(arg2 - arg1); + break; + + case '*': + push_arg(arg2 * arg1); + break; + + case '/': + if (0.0 == arg1) + return R_ERROR; + push_arg(arg2 / arg1); + break; + + case '^': + if (0.0 > arg2) + return R_ERROR; + push_arg(pow(arg2, arg1)); + break; + + case '(': + arg_sptr += 2; + break; + + default: + return ERROR; + } + if (1 > arg_sptr) + return ERROR; + else return op; +} + +/* +** Evaluate one level +*/ + +static int do_paren(void) +{ + int op; + + if (1 > parens--) + return ERROR; + do + { + if (SUCCESS > (op = do_op())) + break; + } while ('('!= op); + return op; +} + +/* +** Stack operations +*/ + +static void push_op(char op) +{ + if ('(' == op) + ++parens; + op_stack[op_sptr++] = op; +} + +static void push_arg(double arg) +{ + arg_stack[arg_sptr++] = arg; +} + +static STATUS pop_arg(double *arg) +{ + *arg = arg_stack[--arg_sptr]; + if (0 > arg_sptr) + return ERROR; + else return SUCCESS; +} + +static STATUS pop_op(int *op) +{ + if (!op_sptr) + return ERROR; + *op = op_stack[--op_sptr]; + return SUCCESS; +} + +/* +** Get an expression +*/ + +static char *getexp(char *str) +{ + char *ptr = str, *tptr = token; + + while (*ptr) + { + if (strchr(delims, *ptr)) + { + if ('-' == *ptr) + { + if (str != ptr && 'E' != ptr[-1]) + break; + } + + else if (str == ptr) + return getop(str); + + else if ('E' == *ptr) + { + if (!isdigit(ptr[1]) && '-' != ptr[1]) + return NULL; + } + else break; + } + + *tptr++ = *ptr++; + } + *tptr = NUL; + + return token; +} + +/* +** Get an operator +*/ + +static char *getop(char *str) +{ + *token = *str; + token[1] = NUL; + return token; +} + +/* +** Remove whitespace & capitalize +*/ + +static void pack(char *str) +{ + char *ptr = str, *p; + + strupr(str); + + for ( ; *ptr; ++ptr) + { + p = ptr; + while (*p && isspace(*p)) + ++p; + if (ptr != p) + strcpy(ptr, p); + } +} diff --git a/reference/C/CONTRIB/SNIP/evsavres.txt b/reference/C/CONTRIB/SNIP/evsavres.txt new file mode 100755 index 0000000..cd525e1 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/evsavres.txt @@ -0,0 +1,5 @@ +To blank EGA/VGA screen - read flipflop at 0x3DA, then write 0x00 + to control port at 0x3C0 + +To restore screen - read flipflop at 0x3DA, then write 0x020 + to control port at 0x3C0 diff --git a/reference/C/CONTRIB/SNIP/except.doc b/reference/C/CONTRIB/SNIP/except.doc new file mode 100755 index 0000000..4e501b5 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/except.doc @@ -0,0 +1,184 @@ +USER-GENERATED EXCEPTIONS IN GENERAL +------------------------------------ + +MS-DOS users can generate exceptions by means of two separate +mechanisms, Ctrl-C and Ctrl-Break. Although these are often treated +the same, they are actually handled in subtly different manners. The +difference in the way these are processed allows a great deal of +flexibility in allowing users to interrupt an executing program. + +When a program is executed, the Ctrl-C Interrupt 23h is set up to +point to a default error handler. This handler is called whenever a +Ctrl-C character is detected in the keyboard input buffer. When a +program terminates in any way, MS-DOS resets the Interrupt 23h vector +to its default state. Note that the Ctrl-C character in the input +buffer is only recognized - and an Interrupt 23h generated - when +retrieving characters from the buffer and if BREAK ON is set. + +The Ctrl-Break Interrupt 1Bh works somewhat differently, though +usually in concert with Interrupt 23h. Whenever the ROM BIOS detects +the Ctrl-Break key combination, the keyboard buffer is flushed and a +Ctrl-C key combination is stuffed in place of the previous contents. +This Ctrl-C will later be detected and processed by Interrupt 23h. +Ctrl-Break processing therefore offers more immediate response than +Ctrl-C processing if the default action is overridden. + +Several caveats are in order here, however. First is the fact that, +unlike Interrupt 23h, MS-DOS does not restore the default state of +Interrupt 1Bh upon program termination. Second is that while Ctrl-C +processing is standardized among the various machines utilizing both +MS-DOS and PC-DOS, Ctrl-Break processing is much less standardized. +Finally, since processing either ultimately relies on trapping +Ctrl-C, either may be ignored for a long period because of the way +that Ctrl-C is detected. + + +HANDLING USER-GENERATED EXCEPTIONS +---------------------------------- + +DOS's default Ctrl-C handler is triggered whenever the Ctrl-C +character is detected in the input buffer. DOS's response is to +simply close all files which were opened using handle functions and +to terminate the program. The limitations of this approach and the +desirability of providing your own exception processing is obvious. + +An equally obvious solution to the default Ctrl-C handler's problems +is to explicitly do your own Ctrl-C exception processing. CCTRAP.ASM +installs and de-installs you own customized exception handler. Note +that the code is written to accept the address of a function specified +with an explicit segment and offset. + +Also note that an explicit de-installation function is provided +despite the fact that DOS restores the default Int 23h vector upon +program termination. The reason this is provided is that you should +always de-install a Ctrl-C interrupt trap before you spawn a child +process. Within your program, if you need to spawn such a process +through any mechanism other than spawning a subordinate shell (more +on this in a second), you should explicitly de-install your interrupt +handlers and re-install them when the subordinate process returns. As +noted, this is unnecessary when the subordinate process is a DOS +shell such as COMMAND.COM, since the shell will reset the interrupts +to their defaults during execution. + +Ctrl-Break processing is much more problematical, though potentially +more powerful. The first problem to deal with is how to assure that +the default Int 1Bh Ctrl-Break handler will be restored upon program +termination. The de-installation function therefore becomes mandatory +in this context rather than optional as in the case of the Int 23h +handler. CBTRAP.ASM shows a sample Ctrl-Break handler. Since Ctrl-Break +processing is much less standardized than Ctrl-C processing, the +safest way to deal with it is to simply set a flag, "cbrcvd", which +informs your program that a Ctrl-Break has been received. Your +program may then poll this flag and take appropriate actions at +"safe" times within your program. + + +WHERE THE CARET-C COMES FROM +---------------------------- + +There's still nothing new here and nothing to prevent the ugly "^C" +being printed to the screen. This is because it is actually printed +by the BIOS during Int 9 processing, long before DOS ever sees it. +What this means is that even though the code in CCTRAP.ASM and +CBTRAP.ASM is fine, it still only provides a framework for solving +our problem. + +TRAPFLAG.ASM is the final trick to banish the "^C". The actual ISR +has to muck around quite a bit with the keyboard hardware, as is to +be expected of an Int 09h replacement. Whenever a Ctrl-C or Ctrl- +Break is detected, it is trapped, and our exception handler called in +place of the original Int 09h handler, after discarding the trapped +key codes. + +Referring to TRAPFLAG.ASM, note that since I need to trap both Ctrl-C +and Ctrl-Break, I adopt the flag approach introduced in CBTRAP.ASM +for dealing with both Ctrl-C and Ctrl-Break processing. Now, rather +than supplying an explicit exception vector, I merely set a global +flag to inform me if either exception has occurred and accept the +responsibility of processing the exceptions within the body of my +program. I've added an extra bit of versatility here by posting +different non-zero values to the flag, "ccrcvd" depending on whether +the exception was a Ctrl-C or Ctrl-Break. + +TRAPDEMO.C is a short C program demonstrating the use of the combined +Ctrl-C/Ctrl-Break handler. Using this approach, your carefully +crafted screens need never more be cluttered with the "^C" uglies. + + +SYSTEM-GENERATED EXCEPTIONS +--------------------------- + +It's usually desirable, in any professional-looking program, to +explicitly trap the Int 24h critical error interrupt to process +system-generated exceptions. CERRINST.ASM is a portable critical +error handler installation program functionally equivalent to the +[_]hardxxx() package in Borland C++ and Microsoft C++ compilers, and +the ceror_xxx() package in Zortech C++. + +It's obvious that writing code to intercept DOS critical error +exceptions is just as simple as intercepting Ctrl-C or Ctrl-Break +exceptions. The real challenge in writing critical error handlers is +in interpretation of the nature of the exception. + +The critical error handler requires more information in order to +decide what action to take than does a Ctrl-C handler. All of this +information is passed in the CPU's registers. Just like a typical +compiler vendor's critical error handler, CERRINST.ASM will simply +pass these registers and leave their interpretation to you. In +CERRINST.ASM, the information required for intelligent critical error +processing is posted in 4 global variables, cedevdvr, cetype, +ceerror, and cereturn. + +Next you need to determine what your program requires of a critical +error handler. CERRTRAP.ASM is a skeletal, yet robust critical error +function which may be called from the handler in CERRINST.ASM. +CERRTRAP.ASM assumes you have set up the following specific error +handlers in the global variables provided: + +FAT error (*FAT_err)(); +Disk read error (*read_err)() +Disk write error (*write_err)() +Terminal error (*term_err)(), +Printer out of paper (*no_paper)(), +All other errors (*fixup_ret)(), + +In the case of an unrecognized error, fixup_ret() is called. A simple +skeleton for this function would be: + +#include /* for _osmajor */ +extern int exerr; /* DOS extended error posted by CERRTRAP.ASM */ +extern int rmvbl; /* removable media flag posted by CERRTRAP.ASM */ +extern int locus; /* extened error locus posted by CERRTRAP.ASM */ +extern int class; /* extened error class posted by CERRTRAP.ASM */ +extern int suggest; /* suggested action posted by CERRTRAP.ASM */ + +int fixup_ret(void) +{ + if (2 < _osmajor) + { + /* analyze DOS extended error information */ + + return appropriate_error_code; + } + + /* cleanup */ + + return 2; /* abort */ +} + +In customing your specific critical error handler functions, there +are several important restrictions to keep in mind. The first is that +no DOS system services may be requested other than Interrupt 21h +functions 01h-0Ch (character I/O), 30h (get DOS version number), and +59h (get extended error information). All registers except AL must be +preserved since DOS sets them up for processing Retry returns prior +to invoking the critical error interrupt. + +Finally, the handler must return with an IRET instruction, passing a +return code in AL to tell DOS what to do next. The available codes +and their actions under various DOS versions are: + + 0 - Ignore + 1 - Retry + 2 - Abort + 3 - Fail (DOS 3.3 and later) diff --git a/reference/C/CONTRIB/SNIP/ext_keys.c b/reference/C/CONTRIB/SNIP/ext_keys.c new file mode 100755 index 0000000..9ec2846 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/ext_keys.c @@ -0,0 +1,56 @@ +/* +** ext_getch() +** +** A getch() work-alike for use with extended keyboards. +** +** Parameters: none +** +** Returns: Extended key code as follows: +** 0->255 Normal key +** 256->511 Numeric pad key or Function key +** 512->767 Cursor pad key or Numeric pad +** "duplicate" key (Enter, /, *, -, +) +** +** Original Copyright 1992 by Bob Stout as part of +** the MicroFirm Function Library (MFL) +** +** This subset version is hereby donated to the public domain. +*/ + +#include +#include + +#define LoByte(x) ((unsigned char)((x) & 0xff)) +#define HiByte(x) ((unsigned char)((unsigned short)(x) >> 8)) + +int ext_getch(void) +{ + int key; + union REGS regs; + + regs.h.ah = 0x10; + int86(0x16, ®s, ®s); + key = regs.x.ax; + + switch (LoByte(key)) + { + case 0: + key = HiByte(key) + 256; + break; + + case 0xe0: + key = HiByte(key) + 512; + break; + + default: + if (0xe0 == HiByte(key)) + key = LoByte(key) + 512; + else + { + if (ispunct(LoByte(key)) && HiByte(key) > 0x36) + key = LoByte(key) + 512; + else key = LoByte(key); + } + } + return key; +} diff --git a/reference/C/CONTRIB/SNIP/ext_keys.h b/reference/C/CONTRIB/SNIP/ext_keys.h new file mode 100755 index 0000000..9704731 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/ext_keys.h @@ -0,0 +1,98 @@ +/* +** ext_getch() header file. +** +** ext_getch() returns: +** +** 0->255 Normal key +** 256->511 Numeric pad key or Function key +** 512->767 Cursor pad key or Numeric pad +** "duplicate" key (Enter, /, *, -, +) +*/ + +int ext_getch(void); + +#define Key_F1 0x13b /* Function keys */ +#define Key_F2 0x13c +#define Key_F3 0x13d +#define Key_F4 0x13e +#define Key_F5 0x13f +#define Key_F6 0x140 +#define Key_F7 0x141 +#define Key_F8 0x142 +#define Key_F9 0x143 +#define Key_F10 0x144 +#define Key_F11 0x185 +#define Key_F12 0x186 +#define Key_CF1 0x15e /* Ctrl-Function keys */ +#define Key_CF2 0x15f +#define Key_CF3 0x160 +#define Key_CF4 0x161 +#define Key_CF5 0x162 +#define Key_CF6 0x163 +#define Key_CF7 0x164 +#define Key_CF8 0x165 +#define Key_CF9 0x166 +#define Key_CF10 0x167 +#define Key_CF11 0x189 +#define Key_CF12 0x18a +#define Key_SF1 0x154 /* Shift-Function keys */ +#define Key_SF2 0x155 +#define Key_SF3 0x156 +#define Key_SF4 0x157 +#define Key_SF5 0x158 +#define Key_SF6 0x159 +#define Key_SF7 0x15a +#define Key_SF8 0x15b +#define Key_SF9 0x15c +#define Key_SF10 0x15d +#define Key_SF11 0x187 +#define Key_SF12 0x188 +#define Key_AF1 0x168 /* Alt-Function keys */ +#define Key_AF2 0x169 +#define Key_AF3 0x16a +#define Key_AF4 0x16b +#define Key_AF5 0x16c +#define Key_AF6 0x16d +#define Key_AF7 0x16e +#define Key_AF8 0x16f +#define Key_AF9 0x170 +#define Key_AF10 0x171 +#define Key_AF11 0x18b +#define Key_AF12 0x18c +#define Key_INS 0x152 /* Numeric pad keys */ +#define Key_DEL 0x153 +#define Key_HOME 0x147 +#define Key_END 0x14f +#define Key_PGUP 0x149 +#define Key_PGDN 0x151 +#define Key_UPARROW 0x148 +#define Key_DNARROW 0x150 +#define Key_LTARROW 0x14b +#define Key_RARROW 0x14d +#define Key_PADMIDDLE 0x14c +#define Key_PADEQ 0x3d +#define Key_PADPLUS 0x22b +#define Key_PADMINUS 0x22d +#define Key_PADASTERISK 0x22a +#define Key_PADSLASH 0x22f +#define Key_C1 0x175 /* Ctrl-Numeric pad keys */ +#define Key_C2 0x191 +#define Key_C3 0x176 +#define Key_C4 0x173 +#define Key_C5 0x18f +#define Key_C6 0x174 +#define Key_C7 0x177 +#define Key_C8 0x18d +#define Key_C9 0x184 +#define Key_PINS 0x252 /* Cursor pad keys */ +#define Key_PDEL 0x253 +#define Key_PHOME 0x247 +#define Key_PEND 0x24f +#define Key_PPGUP 0x249 +#define Key_PPGDN 0x251 +#define Key_PUPARROW 0x248 +#define Key_PDNARROW 0x250 +#define Key_PLTARROW 0x24b +#define Key_PRTARROW 0x24d + +#define Key_ESC 0x1b diff --git a/reference/C/CONTRIB/SNIP/factor.c b/reference/C/CONTRIB/SNIP/factor.c new file mode 100755 index 0000000..4b35d4a --- /dev/null +++ b/reference/C/CONTRIB/SNIP/factor.c @@ -0,0 +1,80 @@ +/* +** factor.c -- print prime factorization of a number +** Ray Gardner -- 1985 -- public domain +** Modified Feb. 1989 by Thad Smith > public domain +** +** This version takes numbers up to the limits of double precision. +*/ + +#include +#include +#include + +int prevfact = 0; +void factor (double); +void show (double, int); + +void main (int argc, char *argv[]) +{ + while ( --argc ) + factor(atof(*++argv)); +} + +void factor (double n) +{ + double d; + int k; + + prevfact = 0; + + d = n+1; /* test for roundoff error */ + if (n+3 != d+2) + { + printf("%0.0f is too large to process.\n", n); + return; + } + if (fmod(n,1.) != 0.0) + { + printf("%f is not an integer.\n",n); + return; + } + printf("%0.0f ",n); + if ( n < 2. ) + { + printf("is less than 2.\n"); + return; + } + else if ( n > 2. ) + { + d = 2; + for ( k = 0; fmod(n,d) == 0.0; k++ ) + n /= d; + if ( k ) + show(d,k); + for ( d = 3; d * d <= n; d += 2 ) + { + for ( k = 0; fmod(n,d) == 0.0; k++ ) + n /= d; + if ( k ) + show(d,k); + } + } + if ( n > 1 ) + { + if ( ! prevfact ) + printf(" is prime"); + else show(n,1); + } + printf("\n"); +} + +void show (double d, int k) +{ + if ( prevfact ) + printf(" * "); + else printf(" = "); + prevfact++; + printf("%0.0f",d); + if ( k > 1 ) + printf("^%d",k); +} diff --git a/reference/C/CONTRIB/SNIP/factoryl.c b/reference/C/CONTRIB/SNIP/factoryl.c new file mode 100755 index 0000000..4ee3079 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/factoryl.c @@ -0,0 +1,103 @@ +/* +** FACTORYL.C +** +** Original Copyright 1992 by Bob Stout as part of +** the MicroFirm Function Library (MFL) +** +** This subset version is hereby donated to the public domain. +*/ + +#include +#include +#include + +#define dfrac(x) ((x)-dround(x)) + +/* Use #defines for Permutations and Combinations */ + +#define log10P(n,r) (log10factorial(n)-log10factorial((n)-(r))) +#define log10C(n,r) (log10P((n),(r))-log10factorial(r)) + +#ifndef PI + #define PI 3.14159265358979323846 +#endif + +#define SQRT2PI sqrt(2 * PI) +#define ONESIXTH (1.0/6.0) + +/* +** DROUND.C - Rounds a double to the nearest whole number +** public domain by Ross Cottrell +*/ + +double dround(double x) +{ + assert(1 == FLT_ROUNDS); + x += 1.0 / DBL_EPSILON; + return x - 1.0 / DBL_EPSILON; +} + +/* +** log10factorial() +** +** Returns the logarithm (base 10) of the factorial of a given number. +** The logarithm is returned since this allows working wil extremely +** large values which would otherwise overflow the F.P. range. +** +** Parameters: 1 - Number whose factorial to return. +** +** Returns: log10() of the passed value, -1.0 if error +** +*/ + +double log10factorial(double N) +{ + if (N < 40) /* Small, explicitly compute */ + { + int i; + double f; + + for (i = 1, f = 1.0; i <= (int)N; ++i) + f *= i; + return log10(f); + } + else /* Large, use approximation */ + { + return log10(SQRT2PI)+((N + 0.5) * + (log10(sqrt(N * N + N + ONESIXTH) / exp(1)))); + } +} + +#ifdef TEST + +#include +#include + +void main(int argc, char *argv[]) +{ + double f, lf; + char *dummy; + + while (--argc) + { + f = strtod((const char *)(*(++argv)), &dummy); + lf = log10factorial(f); + if (171.0 > f) + printf("%.14g! = %.14g\n", f, pow(10.0, lf)); + else + { + printf("%.14g! = %.14ge+%ld\n", f, + pow(10.0, dfrac(lf)), (long)dround(lf)); + } + } + lf = log10C(1000000,750000); + printf("\nJust to dazzle with you with big numbers:\n" + "C(1000000,750000) = %.14ge+%ld\n", + pow(10.0, dfrac(lf)), (long)dround(lf)); + lf = log10P(1000000,750000); + printf("\n...once more:\n" + "P(1000000,750000) = %.14ge+%ld\n", + pow(10.0, dfrac(lf)), (long)dround(lf)); +} + +#endif /* TEST */ diff --git a/reference/C/CONTRIB/SNIP/faskbhit.c b/reference/C/CONTRIB/SNIP/faskbhit.c new file mode 100755 index 0000000..5c14022 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/faskbhit.c @@ -0,0 +1,28 @@ +/* +** by David Goodenough & Bob Stout +*/ + +#ifdef __TURBOC__ + #define FAR far +#else + #define FAR _far +#endif + +#ifndef MK_FP + #define MK_FP(seg,offset) \ + ((void FAR *)(((unsigned long)(seg)<<16) | (unsigned)(offset))) +#endif + +#define biosseg 0x40 + +int fast_kbhit(void) +{ + return *((unsigned FAR *)MK_FP(biosseg, 0x1a)) - + *((unsigned FAR *)MK_FP(biosseg, 0x1c)); +} + +void fast_kbflush(void) +{ + *((unsigned FAR *)MK_FP(biosseg, 0x1a)) = + *((unsigned FAR *)MK_FP(biosseg, 0x1c)); +} diff --git a/reference/C/CONTRIB/SNIP/favail.c b/reference/C/CONTRIB/SNIP/favail.c new file mode 100755 index 0000000..78a7c0d --- /dev/null +++ b/reference/C/CONTRIB/SNIP/favail.c @@ -0,0 +1,54 @@ +/* +** Find out how many more files can be fopen'ed +** +** public domain demo by Bob Stout +*/ + +#include + +#ifdef __TURBOC__ + #define STREAM_BUF _streams + #define FCNT FOPEN_MAX + #define FLAG flags +#else /* MSC, ZTC++ */ + #define STREAM_BUF _iob + #define FCNT _NFILE + #define FLAG _flag +#endif + +int favail(void) +{ + int i, count; + + for (i = count = 0; i < FCNT; ++i) + { + if (0 == STREAM_BUF[i].FLAG) + ++count; + } + return count; +} + +#ifdef TEST + +void main(void) +{ + char *fname = "A$$$$$$$.$$$"; + FILE *fp; + + do + { + int i = favail(); + + printf("You can fopen %d new file%s\n", i, &"s"[i == 1]); + fp = fopen(fname, "w"); + *fname += 1; + } while (fp); + + do + { + printf("removing %s\n", fname); + remove(fname); + } while ('A' <= --(*fname)) ; +} + +#endif /*TEST */ diff --git a/reference/C/CONTRIB/SNIP/fcompare.c b/reference/C/CONTRIB/SNIP/fcompare.c new file mode 100755 index 0000000..7961d02 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/fcompare.c @@ -0,0 +1,59 @@ +/* +** FCOMPARE.C - Compare 2 files +** +** public domain demo by Bob Stout +*/ + +#include +#include +#include + +enum {ERROR = -1, SUCCESS, FAIL}; + +#define BUFSIZE 16384 +static char buf[2][BUFSIZE]; + +int fcompare(const char *fname1, const char *fname2) +{ + FILE *f1, *f2; + int retval = SUCCESS; + + if (NULL == (f1 = fopen(fname1, "rb"))) + return ERROR; + if (NULL != (f2 = fopen(fname2, "rb"))) + { + size_t size1, size2; + + do + { + size1 = fread(buf[0], 1, BUFSIZE, f1); + size2 = fread(buf[1], 1, BUFSIZE, f2); + if (0 == (size1 | size2)) + break; + if ((size1 != size2) || memcmp(buf[0], buf[1], size1)) + { + retval = FAIL; + break; + } + } while (size1 && size2); + fclose(f2); + } + else retval = ERROR; + fclose(f1); + return retval; +} + +#ifdef TEST + +int main(int argc, char *argv[]) +{ + if (3 > argc) + { + puts("Usage: FCOMPARE file1 file2"); + return 1; + } + printf("fcompare(%s, %s) returned %d\n", argv[1], argv[2], + fcompare(argv[1], argv[2])); +} + +#endif /* TEST */ diff --git a/reference/C/CONTRIB/SNIP/fcopy.c b/reference/C/CONTRIB/SNIP/fcopy.c new file mode 100755 index 0000000..6617d6b --- /dev/null +++ b/reference/C/CONTRIB/SNIP/fcopy.c @@ -0,0 +1,55 @@ +/* + * FCOPY.C - copy one file to another. Returns the (positive) + * number of bytes copied, or -1 if an error occurred. + * by: Bob Jarvis + */ + +#include +#include + +#define BUFFER_SIZE 1024 + +long fcopy(char *dest, char *source) +{ + FILE *d, *s; + char *buffer; + size_t incount; + long totcount = 0L; + + s = fopen(source, "rb"); + if(s == NULL) + return -1L; + + d = fopen(dest, "wb"); + if(d == NULL) + { + fclose(s); + return -1L; + } + + buffer = malloc(BUFFER_SIZE); + if(buffer == NULL) + { + fclose(s); + fclose(d); + return -1L; + } + + incount = fread(buffer, sizeof(char), BUFFER_SIZE, s); + + while(!feof(s)) + { + totcount += (long)incount; + fwrite(buffer, sizeof(char), incount, d); + incount = fread(buffer, sizeof(char), BUFFER_SIZE, s); + } + + totcount += (long)incount; + fwrite(buffer, sizeof(char), incount, d); + + free(buffer); + fclose(s); + fclose(d); + + return totcount; +} diff --git a/reference/C/CONTRIB/SNIP/ferrorf.c b/reference/C/CONTRIB/SNIP/ferrorf.c new file mode 100755 index 0000000..7bf74d1 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/ferrorf.c @@ -0,0 +1,25 @@ +/* FERRORF.C +** Prints error message with printf() formatting syntax, then a colon, +** then a message corressponding to the value of errno, then a newline. +** Output is to filehandle. +** +** Public Domain by Mark R. Devlin, free usage is permitted. +*/ + +#include +#include +#include +#include + +int ferrorf(FILE *filehandle, const char *format, ...) +{ + int vfp, fp; + va_list vargs; + + vfp = fp = 0; + va_start(vargs, format); + vfp = vfprintf(filehandle, format, vargs); + va_end(vargs); + fp = fprintf(filehandle, ": %s\n", sys_errlist[errno]); + return ((vfp==EOF || fp==EOF) ? EOF : (vfp+fp)); +} diff --git a/reference/C/CONTRIB/SNIP/filcount.c b/reference/C/CONTRIB/SNIP/filcount.c new file mode 100755 index 0000000..40a7d31 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/filcount.c @@ -0,0 +1,93 @@ +/* +** FILCOUNT.C - counts directories and /or files in a directory +** +** public domain demo by Bob Stout +*/ + +#include +#include + +#undef TRUE +#undef FALSE +typedef enum {ERROR = -1, FALSE, TRUE} LOGICAL; + +#ifdef __ZTC__ + #include +#elif defined(__TURBOC__) + #include + #include + #define _dos_findfirst(f,a,b) findfirst(f,b,a) + #define _dos_findnext(b) findnext(b) + #define find_t ffblk + #define _A_SUBDIR FA_DIREC + #define attrib ff_attrib + #define name ff_name +#else /* assume MSC/QC */ + #include + #include +#endif + +#undef SUCCESS +#define SUCCESS 0 + +#define LAST_CHAR(str) (str)[strlen(str) - 1] + +unsigned DirCount = 0, FileCount = 0; + +/* +** Arguments: 1 - directory to search +** 2 - search subdirectories: TRUE or FALSE +*/ + +void do_dir(char *path, int recurse_flag) +{ + char search[67], new[67]; + struct find_t ff; + + strcpy(search, path); + if ('\\' != LAST_CHAR(search)) + strcat(search, "\\"); + strcat(search, "*.*"); + if (SUCCESS == _dos_findfirst(search, 0xff, &ff)) do + { + if ('.' == *ff.name) + continue; + if (ff.attrib & _A_SUBDIR) + { + DirCount++; + if (recurse_flag) + { + strcpy(new, path); + if ('\\' != LAST_CHAR(new)) + strcat(new, "\\"); + strcat(new, ff.name); + do_dir(new, recurse_flag); + } + } + else FileCount++; + } while (SUCCESS == _dos_findnext(&ff)); +} + +/* +** Simple resursive file/directory counter +** +** Usage: FILCOUNT [path_name] [{Y | N}] +** +** Notes: 1. If a path name isn't specified, the current directory is assumed +** 2. Default recursion flag is FALSE +** 3. Path must be specified in order to specify the recursion flag +*/ + +void main(int argc, char *argv[]) +{ + char *Dir ="."; + LOGICAL recurse = FALSE; + + if (1 < argc) + Dir = argv[1]; + if (2 < argc) + recurse = (NULL != strchr("Yy", *argv[2])); + do_dir(Dir, recurse); + printf("Counted: %d Directories and %d Files\n", + DirCount, FileCount); +} diff --git a/reference/C/CONTRIB/SNIP/file_id.diz b/reference/C/CONTRIB/SNIP/file_id.diz new file mode 100755 index 0000000..03fc75f --- /dev/null +++ b/reference/C/CONTRIB/SNIP/file_id.diz @@ -0,0 +1,6 @@ +The SNIPPETS collection is an archive +of over 300 separate files, over 30,000 +lines of mostly C/C++ source code - all +public domain and freeware - which +contains the best answers to "How do +I..." questions. diff --git a/reference/C/CONTRIB/SNIP/files.c b/reference/C/CONTRIB/SNIP/files.c new file mode 100755 index 0000000..caa7ac5 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/files.c @@ -0,0 +1,93 @@ +/* +** FILES.C: A program to determine the number of file handles +** +** Released in to the Public Domian by Matthew Hunt @ 1:129/135, in the +** hopes that no "programmer" will be so lazy that he|she simple reads +** the CONFIG.SYS file ever again. +** +** Any improvements and modifications are welcome, but I ask that all +** modified versions also be placed into the Public Domain. +** +** Information on the List of Lists and SFT format was provided by +** PC Magazine November 26, 1991, and PC Interrupts by Ralf Brown +** and Jim Kyle. FILES.C was originally written for Power C. +** +** Modifcations for other compiler support by Bob Stout @ 1:106/2000.6 +*/ + +#include + +#ifdef __TURBOC__ + #define FAR far +#else + #define FAR _far +#endif + +#ifndef MK_FP + #define MK_FP(seg,offset) \ + ((void FAR *)(((unsigned long)(seg)<<16) | (unsigned)(offset))) +#endif + +/* +** This is the format for a System File Table header. SFT's are a linked +** list in which the header points to the next SFT, is followed by the +** number of FILES in this SFT, and ends with the FILES themselves, which +** are not important here. +*/ + +struct SFT_HEADER { + struct SFT_HEADER (FAR *next); + unsigned number; +}; + +/* +** Walk the SFT linked list, counting file handles as we go +*/ + +int files(void) +{ + struct SFT_HEADER (FAR *sft); + unsigned int segment, offset; + int count=0; + union REGS regs; + struct SREGS sregs; + + /* Get ptr to List of Lists in ES:DX */ + + regs.x.ax = 0x5200; + segread(&sregs); + intdosx(®s, ®s, &sregs); + + /* Get ssss:oooo to first SFT */ + + segment = *((unsigned FAR *)(MK_FP(sregs.es, regs.x.bx + 6))); + offset = *((unsigned FAR *)(MK_FP(sregs.es, regs.x.bx + 4))); + + /* Point our structure to it. */ + + sft = MK_FP(segment, offset); + + do + { + count += sft->number; /* Add the number of FILES */ + sft = sft->next; /* Point to next one */ + } while(FP_OFF(sft->next) != 0x0FFFF); /* Last one in the chain */ + + /* Add the FILES for the last entry */ + + count += sft->number; + return count; +} + +#ifdef TEST + +#include +#include + +int main(void) +{ + printf("Number of FILES entries: %d", files()); + return EXIT_SUCCESS; +} + +#endif /* TEST */ diff --git a/reference/C/CONTRIB/SNIP/fln_fix.c b/reference/C/CONTRIB/SNIP/fln_fix.c new file mode 100755 index 0000000..e1ded2e --- /dev/null +++ b/reference/C/CONTRIB/SNIP/fln_fix.c @@ -0,0 +1,142 @@ +/* +** FLN_FIX.C +** +** Original Copyright 1988-1991 by Bob Stout as part of +** the MicroFirm Function Library (MFL) +** +** This subset version is functionally identical to the +** version originally published by the author in Tech Specialist +** magazine and is hereby donated to the public domain. +*/ + +#include +#include +#include +#include + +#define LAST_CHAR(string) (((char *)string)[strlen(string)-1]) + +typedef enum {ERROR = -1, FALSE, TRUE} LOGICAL; + +char *unix2dos(char *path); + +/****************************************************************/ +/* */ +/* Function to `crunch' dot directories and check for */ +/* DOS-valid path strings. Drive specifiers in the path */ +/* ignored. */ +/* */ +/****************************************************************/ + +char *fln_fix(char *path) +{ + LOGICAL dir_flag = FALSE, root_flag = FALSE; + char *r, *p, *q, *s; + + if (path) + strupr(path); + + /* Ignore leading drive specs */ + + if (NULL == (r = strrchr(path, ':'))) + r = path; + else ++r; + + unix2dos(r); /* Convert Unix to DOS style */ + + while ('\\' == *r) /* Ignore leading backslashes */ + { + if ('\\' == r[1]) + strcpy(r, &r[1]); + else + { + root_flag = TRUE; + ++r; + } + } + + p = r; /* Change "\\" to "\" */ + while (NULL != (p = strchr(p, '\\'))) + { + if ('\\' == p[1]) + strcpy(p, &p[1]); + else ++p; + } + + while ('.' == *r) /* Scrunch leading ".\" */ + { + if ('.' == r[1]) + { + /* Ignore leading ".." */ + + for (p = (r += 2); *p && (*p != '\\'); ++p) + ; + } + else + { + for (p = r + 1 ;*p && (*p != '\\'); ++p) + ; + } + strcpy(r, p + ((*p) ? 1 : 0)); + } + + while ('\\' == LAST_CHAR(path)) /* Strip trailing backslash */ + { + dir_flag = TRUE; + LAST_CHAR(path) = '\0'; + } + + s = r; + + /* Look for "\." in path */ + + while (NULL != (p = strstr(s, "\\."))) + { + if ('.' == p[2]) + { + /* Execute this section if ".." found */ + + q = p - 1; + while (q > r) /* Backup one level */ + { + if (*q == '\\') + break; + --q; + } + if (q > r) + { + strcpy(q, p + 3); + s = q; + } + else if ('.' != *q) + { + strcpy(q + ((*q == '\\') ? 1 : 0), + p + 3 + ((*(p + 3)) ? 1 : 0)); + s = q; + } + else s = ++p; + + } + else + { + /* Execute this section if "." found */ + + q = p + 2; + for ( ;*q && (*q != '\\'); ++q) + ; + strcpy (p, q); + } + } + + if (root_flag) /* Embedded ".." could have bubbled up to root */ + { + for (p = r; *p && ('.' == *p || '\\' == *p); ++p) + ; + if (r != p) + strcpy(r, p); + } + + if (dir_flag) + strcat(path, "\\"); + return path; +} diff --git a/reference/C/CONTRIB/SNIP/flnorm.c b/reference/C/CONTRIB/SNIP/flnorm.c new file mode 100755 index 0000000..79337ab --- /dev/null +++ b/reference/C/CONTRIB/SNIP/flnorm.c @@ -0,0 +1,158 @@ +/* +** FLNORM.C - Normalize DOS file names +** +** Original Copyright 1988-1991 by Bob Stout as part of +** the MicroFirm Function Library (MFL) +** +** This subset version is functionally identical to the +** version originally published by the author in Tech Specialist +** magazine and is hereby donated to the public domain. +*/ + +#include +#include +#ifdef __TURBOC__ + #include +#else + #include +#endif +#include +#include + +#define MAX_FLEN 67 +#define LAST_CHAR(string) (((char *)string)[strlen(string)-1]) + +typedef enum {ERROR = -1, FALSE, TRUE} LOGICAL; + +/* +** NOTE: Uses the following functions, also in SNIPPETS! +*/ + +int chdrv(int); /* In DRVALID.C */ +char *unix2dos(char *); /* In UNIX2DOS.C */ +char *fln_fix(char *); /* In FLN_FIX.C */ + +int flnorm(char *in_name, char *out_name) +{ + LOGICAL dir_flag = FALSE, new_drv = FALSE, root_flag; + int status = 0, level = 0; + char *p, *out; + static char drive[2][3]; + static char file[14]; + static char I_am_here[MAX_FLEN]; + static char I_am_there[MAX_FLEN]; + static char remember[MAX_FLEN]; + + getcwd(I_am_here, MAX_FLEN); + if (!in_name || !in_name[0]) + { + strcpy(out_name, I_am_here); + goto ERRexit; + } + strncpy(drive[0], I_am_here, 2); + drive[0][2] = '\0'; + if (':' == in_name[1]) + { /* If a drive is specified */ + if (chdrv(in_name[0])) + { /* If the drive is invalid */ + status = ERROR; + goto ERRexit; + } + new_drv = TRUE; + getcwd(remember, MAX_FLEN); + strncpy(drive[1], remember, 2); + drive[1][2] = '\0'; + } + else + { /* If a drive isn't specified */ + if (NULL != (p = strchr(in_name, ':'))) + { /* If filename is illegal */ + status = ERROR; + goto ERRexit; + } + } + unix2dos(in_name); + if (new_drv) + { + if ('\\' == in_name[2]) + strcpy(out_name, drive[1]); + else + { + strcpy(out_name, remember); + if ('\\' != LAST_CHAR(remember)) + strcat(out_name, "\\"); + } + } + else + { + strcpy(out_name, drive[0]); + if ('\\' != *in_name) + { + strcat(out_name, I_am_here); + if ('\\' != LAST_CHAR(I_am_here)) + strcat(out_name, "\\"); + } + } + strcat(out_name, &in_name[(new_drv) ? 2 : 0]); + fln_fix(out_name); + out = &out_name[2]; + if (!(*out)) + goto ERRexit; + while ('\\' == LAST_CHAR(out)) + { /* Strip trailing `\'s */ + LAST_CHAR(out_name) = '\0'; + dir_flag = TRUE; + } + if (!(*out)) + { + if (dir_flag) + { + strcat(out, "\\"); + goto ERRexit; + } + else goto BADPATH; + } + if (NULL != (p = strrchr(out_name, '\\'))) + strcpy(file, p); /* Save filename */ + if (chdir(out)) + { /* If can't move to path */ + if ((!dir_flag) && p) + { /* If there was a separate path */ + *p = '\0'; + if (!(*out)) + { /* Back at the root, handle it */ + strcpy(p, "\\"); + strcpy(file, &file[1]); + } + if (chdir(out)) + { /* If we can't move to path */ + *p = '\\'; + goto BADPATH; + } + ++level; /* Flag we stripped name */ + } + else + { /* No path as specified */ + if (p) + { +BADPATH: status = ERROR; + goto ERRexit; + } + } + } + getcwd(I_am_there, MAX_FLEN); /* Get normalized path */ + strupr(I_am_there); + strcpy(out_name, I_am_there); + if (level) + strcat(out_name, file); +ERRexit: + if (new_drv) + { + chdir(remember); + chdrv(I_am_here[0]); + } + chdir(I_am_here); + if (status) + out_name[0] = '\0'; + return status; +} diff --git a/reference/C/CONTRIB/SNIP/flopcopy.c b/reference/C/CONTRIB/SNIP/flopcopy.c new file mode 100755 index 0000000..18b16d7 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/flopcopy.c @@ -0,0 +1,120 @@ +/* +** FLOPCOPY.C +** +** Copy a floppy to a hard disk directory with directory recursion +** Public domain, uses functions from SNIPPETS. +*/ + +#include +#include +#include +#include +#include +#include + +#ifdef __TURBOC__ + #include + #include + #define _dos_findfirst(f,a,b) findfirst(f,b,a) + #define _dos_findnext(b) findnext(b) + #define find_t ffblk + #define _A_SUBDIR FA_DIREC + #define attrib ff_attrib + #define name ff_name +#else + #include + #ifdef __ZTC__ + #include + #ifndef _A_SUBDIR + #define _A_SUBDIR FA_DIREC + #endif + #else /* assume MSC/QC */ + #include + #include + #include + #endif +#endif + +#include + +#undef SUCCESS +#define SUCCESS 0 + +#undef NUL +#define NUL '\0' + +#define LAST_CHAR(s) (((char *)s)[strlen(s) - 1]) + +int file_copy(char *,char *); /* In Wb_Fcopy.C */ +void do_dir(char *, char *); + +/* +** Copy a floppy to an HD subdirectory +*/ + +int main(int argc, char *argv[]) +{ + char fdrv[4] = "A:\\", target[FILENAME_MAX]; + + if (3 > argc) + { + puts("Usage: FLOPCOPY drive_letter subdir"); + puts("where: drive_letter is \"A\" or \"B\" (colon optional)"); + puts(" subdir is drive:dir target, e.g. \"C:\\FLOPSTUF\""); + return EXIT_FAILURE; + } + *fdrv = *argv[1]; + strcpy(target, argv[2]); + if ('\\' != LAST_CHAR(target)) + strcat(target, "\\"); + + do_dir(fdrv, target); +} + +/* +** Process a directory (SNIPPETS: Treedir.C, modified) +*/ + +void do_dir(char *from, char *to) +{ + char search[FILENAME_MAX], new[FILENAME_MAX], newto[FILENAME_MAX]; + struct find_t ff; + + strcat(strcpy(search, from), "*.*"); + if (SUCCESS == _dos_findfirst(to, 0xff, &ff)) + { + if (0 == (ff.attrib & _A_SUBDIR)) + { + printf("*** %s Exists and is not a directory!\n", to); + return; + } + } + else + { + strcpy(newto, to); + if ('\\' == LAST_CHAR(newto)) + LAST_CHAR(newto) = NUL; + mkdir(newto); + } + if (SUCCESS == _dos_findfirst(search, 0xff, &ff)) do + { + if (ff.attrib & _A_SUBDIR && '.' != *ff.name) + { + strcat(strcat(strcpy(new, from), ff.name), "\\"); + strcat(strcat(strcpy(newto, to), ff.name), "\\"); + do_dir(new, newto); + } + else + { + char file1[FILENAME_MAX], file2[FILENAME_MAX]; + + if ((ff.attrib & (_A_SUBDIR | _A_VOLID)) || '.' == *ff.name) + continue; + strcat(strcpy(file1, from), ff.name); + strcat(strcpy(file2, to), ff.name); + if (SUCCESS != file_copy(file1, file2)) + printf("*** Unable to copy %s to %s\n", file1, file2); + else printf("Copied %s to %s\n", file1, file2); + } + } while (SUCCESS == _dos_findnext(&ff)); +} diff --git a/reference/C/CONTRIB/SNIP/fmemops.c b/reference/C/CONTRIB/SNIP/fmemops.c new file mode 100755 index 0000000..081af90 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/fmemops.c @@ -0,0 +1,52 @@ +/* +** FMEMOPS.C - Emulate MSC's far memory functions in BC++ & ZTC++ +** +** Original Copyright 1988-1992 by Bob Stout as part of +** the MicroFirm Function Library (MFL) +** +** This subset version is hereby donated to the public domain. +*/ + +#include +#include +#include + +#if defined(__TURBOC__) || defined(__ZTC__) + +#ifdef __TURBOC__ + #define FAR far +#else + #define FAR _far +#endif + +typedef unsigned char FAR *FarBytePtr; + +void FAR * _fmemcpy(void FAR *dest, void FAR *src, size_t count) +{ + movedata(FP_SEG(src), FP_OFF(src), FP_SEG(dest), FP_OFF(dest), count); + return dest; +} + +void FAR * _fmemmove(void FAR *dest, void FAR *src, size_t count) +{ + void FAR *target = dest; + FarBytePtr to = (FarBytePtr)dest, from = (FarBytePtr)src; + + if (src >= dest) + _fmemcpy(dest, src, count); + else for (to += count, from += count; count; --count) + *--to = *--from; + return target; +} + +void FAR * _fmemset(void FAR *dest, int ch, size_t count) +{ + void FAR *target = dest; + FarBytePtr to = (FarBytePtr)dest; + + for ( ; count; --count) + *to++ = (unsigned char) ch; + return target; +} + +#endif diff --git a/reference/C/CONTRIB/SNIP/fmtmoney.c b/reference/C/CONTRIB/SNIP/fmtmoney.c new file mode 100755 index 0000000..8d9b1ee --- /dev/null +++ b/reference/C/CONTRIB/SNIP/fmtmoney.c @@ -0,0 +1,119 @@ +/* +** FMTMONEY.C - Format a U.S. dollar value into a numeric string +** +** public domain demo by Bob Stout +*/ + +#include +#include +#include +#include + +#define Form(s,a) bufptr += sprintf(bufptr, s, a) + +static char buf[256], *bufptr; + +static char *units[] = {"Zero", "One", "Two", "Three", "Four", + "Five", "Six", "Seven", "Eight", "Nine", + "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", + "Fifteen", "Sixteen", "Seventeen", "Eighteen", + "Nineteen"}, + + *tens[] = {"Twenty", "Thirty", "Forty", "Fifty", "Sixty", + "Seventy", "Eighty", "Ninety"}; + +static void form_group(int, char *); + +/* +** Call with double amount +** Rounds cents +** Returns string in a static buffer +*/ + +char *fmt_money(double amt) +{ + int temp; + double dummy, cents = modf(amt, &dummy); + + *buf = '\0'; + bufptr = buf; + + temp = (int)(amt/1E12); + if (temp) + { + form_group(temp, "Trillion"); + amt = fmod(amt, 1E12); + } + + temp = (int)(amt/1E9); + if (temp) + { + form_group(temp, "Billion"); + amt = fmod(amt, 1E9); + } + + temp = (int)(amt/1E6); + if (temp) + { + form_group(temp, "Million"); + amt = fmod(amt, 1E6); + } + + temp = (int)(amt/1E3); + if (temp) + { + form_group(temp, "Thousand"); + amt = fmod(amt, 1E3); + } + form_group((int)amt, ""); + + if (buf == bufptr) + Form("%s ", units[0]); + + temp = (int)(cents * 100. + .5); + sprintf(bufptr, "& %02d/100", temp); + + return buf; +} + +/* +** Process each thousands group +*/ + +static void form_group(int amt, char *scale) +{ + if (buf != bufptr) + *bufptr++ = ' '; + + if (100 <= amt) + { + Form("%s Hundred ", units[amt/100]); + amt %= 100; + } + if (20 <= amt) + { + Form("%s", tens[(amt - 20)/10]); + if (0 != (amt %= 10)) + { + Form("-%s ", units[amt]); + } + else Form("%s", " "); + } + else if (amt) + { + Form("%s ", units[amt]); + } + + Form("%s", scale); +} + +#ifdef TEST + +void main(int argc, char *argv[]) +{ + double amt = atof(argv[1]); + + printf("fmt_money(%g) = %s\n", amt, fmt_money(amt)); +} + +#endif diff --git a/reference/C/CONTRIB/SNIP/fndislot.c b/reference/C/CONTRIB/SNIP/fndislot.c new file mode 100755 index 0000000..2999596 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/fndislot.c @@ -0,0 +1,48 @@ +/* +** Originally published as part of the MicroFirm Function Library +** +** Copyright 1990, Robert B.Stout +** +** Subset version released to the public domain, 1992 +** +** Function to locate an unused user interrupt vector. +*/ + +#ifdef __ZTC__ + #include +#else + #include + #ifdef __TURBOC__ + #define GETVECT getvect + #define FAR far + #define INTERRUPT interrupt + #else /* assume MSC */ + #define GETVECT _dos_getvect + #define FAR _far + #define INTERRUPT _interrupt + #endif + #define FNULL (void (FAR *)())(0L) +#endif + +unsigned findIslot(void) +{ +#ifdef __ZTC__ + unsigned int_no, seg, ofs; + + for (int_no = 0x60; int_no < 0x6f; ++int_no) + { + int_getvector(int_no, &seg, &ofs); + if (0U == (seg | ofs)) + return int_no; + } +#else /* MSC/BC/TC */ + unsigned int_no; + + for (int_no = 0x60; int_no < 0x6f; ++int_no) + { + if (FNULL != (void (FAR *)())GETVECT(int_no)) + return int_no; + } +#endif + return 0; +} diff --git a/reference/C/CONTRIB/SNIP/format.c b/reference/C/CONTRIB/SNIP/format.c new file mode 100755 index 0000000..5707118 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/format.c @@ -0,0 +1,56 @@ +/* +** FORMAT.C - Use DOS FORMAT to format a diskette +** +** Original Copyright 1992 by Bob Stout as part of +** the MicroFirm Function Library (MFL) +** +** This subset version is hereby donated to the public domain. +*/ + +#include +#include + +enum {ERROR = -1, SUCCESS}; + +/* +** format +** +** Formats a specified floppy disk with optional switches. +** +** Parameters: 1 - Drive letter ('A', 'B', ...) to format +** 2 - Formatting switches in FORMAT.COM format, e.g. "/4" +** 3 - Volume label +** +** Returns: SUCCESS or ERROR +*/ + +int format(char drive, char *switches, char *vlabel) +{ + char command[128], fname[13]; + FILE *tmpfile; + + tmpnam(fname); + if (NULL == (tmpfile = fopen(fname, "w"))) + return ERROR; /* Can't open temp file */ + fprintf(tmpfile, "\n%s\nN\n", vlabel); + fclose(tmpfile); + + sprintf(command, "format %c: /V %s < %s > NUL", drive, switches, fname); + + system(command); + + remove(fname); + + return SUCCESS; +} + +#ifdef TEST + +void main(void) +{ + int retval = format((char)'a', "/4", "dummy_test"); + + printf("format() returned %d\n", retval); +} + +#endif diff --git a/reference/C/CONTRIB/SNIP/fpswitch.c b/reference/C/CONTRIB/SNIP/fpswitch.c new file mode 100755 index 0000000..6645754 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/fpswitch.c @@ -0,0 +1,81 @@ +/* +** FPSELECT.C - Demonstrates using function pointers in lieu of switches +*/ + +#include /* for NULL */ + +/* Declare your functions here */ + +char *cpfunc1(int); +char *cpfunc2(int); +char *cpfunc3(int); + +void vfunc1(void); +void vfunc2(void); +void vfunc3(void); +void vfunc4(void); + +/* +** Old ways using switch statements +*/ + +char *oldcpswitch(int select, int arg) +{ + switch (select) + { + case 1: + return cpfunc1(arg); + + case 2: + return cpfunc2(arg); + + case 3: + return cpfunc3(arg); + + default: + return NULL; + } +} + +void oldvswitch(int select) +{ + switch (select) + { + case 1: + vfunc1(); + break; + + case 2: + vfunc2(); + break; + + case 3: + vfunc3(); + break; + + case 4: + vfunc4(); + break; + } +} + +/* +** Using function pointers +*/ + +char *newcpswitch(int select, int arg) +{ + char *(*cpfunc[3])(int) = { cpfunc1, cpfunc2, cpfunc3 }; + + if (select < 1 || select > 3) + return NULL; + return (*cpfunc[select-1])(arg); +} + +void newvswitch(int select) +{ + void (*vfunc[4])(void) = { vfunc1, vfunc2, vfunc3, vfunc4 }; + + if (select > 0 && select < 5) + (*vfunc[select-1])(); +} diff --git a/reference/C/CONTRIB/SNIP/fraction.c b/reference/C/CONTRIB/SNIP/fraction.c new file mode 100755 index 0000000..35a4b4c --- /dev/null +++ b/reference/C/CONTRIB/SNIP/fraction.c @@ -0,0 +1,91 @@ +/* +** FRACTION.C - Compute continued fraction series +** +** cfrac() donated to the public domain by the author, Thad Smith +** original Fraction.C, public domain by Bob Stout, modified to use cfrac() +*/ + +#include +#include + +#define MAX_LENGTH 100 + +long double cfrac(long double x, long double *p, long double *q, int bits) +{ + double v; /* integer in series */ + long double del; /* x - v */ + long double z; /* approximated value from truncated series */ + long double t; /* temp */ + long double p0 = 0.0, q0 = 0.0; /* last p, q */ + long double imax; /* max for p, q */ + static long double cf[MAX_LENGTH]; /* continued fraction integers */ + int i, j, ntimes = MAX_LENGTH;; + + if (x < 0) + x = -x; + imax = floor(pow(2.0, bits)) - 1.0; + for (i = 0; i < ntimes; i++) + { + v = floor((double)x); + cf[i] = v; + z = cf[i]; + *p = z; *q = 1; + for (j = i; j--; ) + { + z = cf[j] + 1.0/z; + t = *p; + *p = cf[j] * (*p) + (*q); + *q = t; + } + del = x-v; + if (del < DBL_EPSILON) + break; + if ((*p > imax) || (*q > imax)) + { + *p = p0; + *q = q0; + break; + } + else + { + p0 = *p; + q0 = *q; + } + x = 1.0 / del; + } + return (*p)/(*q); +} + +/* +** Remove everything below this to use cfrac() as a stand-alone function +*/ + +#include +#include + +main (int argc, char *argv[]) +{ + long double x; /* value to be approximated */ + long double r,p,q; /* approx ratio r = p/q */ + int bits; /* bits of precision */ + + if (argc < 2 || argc > 3) + { + puts ("Use: FRACTION value [precision]"); + puts ("where value = floating point value to generate " + "continued fraction"); + puts (" precision (optional) = bits in " + "numerator/denominator"); + return 1; + } + sscanf (argv[1], "%Lf", &x); + if (argc == 3) + bits = atoi(argv[2]); + else bits = 32; + + cfrac(x, &p, &q, bits); + printf("\n[%.20Lf]\n%.0Lf/%.0Lf = %lXh/%lXh = %.20Lf\n", + x, p, q, (long)p, (long)q, r = p/q); + printf("Error = %.10Lg, (%.10Lf%%)\n", r - x, 100. * (r - x) / x); + return EXIT_SUCCESS; +} diff --git a/reference/C/CONTRIB/SNIP/fscanbin.c b/reference/C/CONTRIB/SNIP/fscanbin.c new file mode 100755 index 0000000..9efa1c0 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/fscanbin.c @@ -0,0 +1,115 @@ +/* fscanbin.c -- scan binary fields via format string +** +** public domain by Ray Gardner Englewood, Colorado 11/29/89 +** +** Usage: fscanbin(FILE *fp, char *format, ...) +** +** where format string contains specifiers: +** -ddd means skip ddd bytes +** i means read a 16-bit int +** l means read a 32-bit int +** sddd means read a character string of up to ddd bytes +** reads up to a nul byte if ddd is zero or missing +** cnnn means read a character field of nnn bytes (not nul-terminated) +** reads one byte if nnn is zero or missing +*/ + +#include +#include +#include +#include + +typedef unsigned short int16; +typedef unsigned long int32; + +#define int16swap(n) (*n = (*n << 8) | (*n >> 8)) + +#define int32swap(n) (\ + int16swap(&((int16 *)n)[0]),\ + int16swap(&((int16 *)n)[1]),\ + *n = (*n << 16) | (*n >> 16)\ + ) + +#define maxk 32767 + +int fscanbin (FILE *fp, char *format, ...) +{ + va_list argp; + unsigned char *p; + unsigned k; + int c; + char *charp; + int16 *int16p; + int32 *int32p; + int bytes_read; + + bytes_read = 0; + va_start(argp, format); + for ( p = (unsigned char *)format; *p; ) + { + switch( *p & 0xFF ) + { + case '-': + for ( k = 0, c = *++p; isdigit(c); c = *++p ) + k = 10 * k + c - '0'; + if ( k == 0 ) + k = 1; + if ( fseek(fp, (long)k, SEEK_CUR) ) + return -2; /* i/o error */ + bytes_read += k; + break; + + case 'i': + int16p = va_arg(argp, int16 *); + if ( fread((void *)int16p, sizeof(int16), 1, fp) != 1 ) + return -2; /* i/o error */ +#if SWAP16 + int16swap(int16p); +#endif + p++; + bytes_read += sizeof(int16); + break; + + case 'l': + int32p = va_arg(argp, int32 *); + if ( fread((void *)int32p, sizeof(int32), 1, fp) != 1 ) + return -2; /* i/o error */ +#if SWAP32 + int32swap(int32p); +#endif + p++; + bytes_read += sizeof(int32); + break; + + case 's': + charp = va_arg(argp, char *); + for ( k = 0, c = *++p; isdigit(c); c = *++p ) + k = 10 * k + c - '0'; + do + { + c = getc(fp); + if ( c == EOF ) + return -2; + *charp++ = (char)c; + bytes_read++; + } while ( c && (k == 0 || --k) ); + break; + + case 'c': + charp = va_arg(argp, char *); + for ( k = 0, c = *++p; isdigit(c); c = *++p ) + k = 10 * k + c - '0'; + if ( k == 0 ) + k = 1; + if ( fread((void *)charp, sizeof(char), k, fp) != k ) + return -2; /* i/o error */ + bytes_read += k; + break; + + default: + return -1; /* bad format */ + } + } + va_end(argp); + return bytes_read; +} diff --git a/reference/C/CONTRIB/SNIP/fsize.c b/reference/C/CONTRIB/SNIP/fsize.c new file mode 100755 index 0000000..319a719 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/fsize.c @@ -0,0 +1,78 @@ +/* +** FSIZE.C - Determine apparent file size of buffered file. Returns size +** corrected for text mode character translation. +** +** public domain demo by Bob Stout +*/ + +#include +#include + +long fsize(FILE *fp) +{ + size_t bufsize, bytes_read; + char *bufptr; + long size = 0L, pos; + + for (bufsize = 0x8000; NULL == (bufptr = malloc(bufsize)); bufsize /= 2) + ; + if (!bufptr) + return -1L; + pos = ftell(fp); + do + { + bytes_read = fread(bufptr, sizeof(char), bufsize, fp); + size += bytes_read; + } while (bytes_read); + free(bufptr); + fseek(fp, pos, SEEK_SET); + return size; +} + +#ifdef TEST + +#include + +#ifdef MSDOS + #define fl(x) filelength(x) + #define getsize(fp) fl(fileno(fp)) +#else + #define fl(x) puts("Install compiler-specific file length function here") + #define getsize(fp) fl(fp) +#endif + +int main(int argc, char *argv[]) +{ + FILE *fp; + long size, csize, lsize; + char buf[256]; + + while (--argc) + { + if (NULL == (fp = fopen(*++argv, "r"))) + printf("Can't open %s\n", *argv); + + size = getsize(fp); + printf("\n\"Real\" size of %s is %ld\n", *argv, size); + + for (csize = 0L; EOF != fgetc(fp); ++csize) + ; + rewind(fp); + + for (lsize = 0L; !feof(fp); ) + { + if (NULL != fgets(buf, 256, fp)) + lsize += strlen(buf); + } + rewind(fp); + + printf("fsize() returned a size = %s is %ld\n", + *argv, fsize(fp)); + printf("Reading chars returned an apparent size of %ld\n", + csize); + printf("Reading lines returned an apparent size of %ld\n", + lsize); + } +} + +#endif diff --git a/reference/C/CONTRIB/SNIP/fsm.c b/reference/C/CONTRIB/SNIP/fsm.c new file mode 100755 index 0000000..58c4220 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/fsm.c @@ -0,0 +1,37 @@ +/* +** code snippet demonstrating a finite state machine (FSM) +*/ + +typedef enum {s0,s1,s2,s3,s4,...,sn,sexit} state; + +state nextstate; +int done = 0; + +nextstate = s0; /* set up to start with the first state */ +while(!done) + switch(nextstate) + { + case s0: + nextstate = do_state_0(); + break; + case s1: + nextstate = do_state_1(); + break; + case s2: + nextstate = do_state_2(); + break; + case s3: + . + . + . + . + case sn: + nextstate = do_state_n(); + break; + case sexit: + done = TRUE; + break; + default: + /* some sort of unknown state */ + break; + } diff --git a/reference/C/CONTRIB/SNIP/ftime.c b/reference/C/CONTRIB/SNIP/ftime.c new file mode 100755 index 0000000..74690a9 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/ftime.c @@ -0,0 +1,58 @@ +/* +** Public domain by Jeff Dunlop & Bob Stout +*/ + +#ifndef __TURBOC__ + +#include +#include "ftime.h" + +#ifdef __ZTC__ + #pragma ZTC align 1 + #define DOS_GETFTIME dos_getftime + #define DOS_SETFTIME dos_setftime +#else + #pragma pack(1) + #define DOS_GETFTIME _dos_getftime + #define DOS_SETFTIME _dos_setftime +#endif + +int _cdecl getftime (int handle, struct ftime *ftimep) +{ + int retval = 0; + union + { + struct + { + unsigned time; + unsigned date; + } msc_time; + struct ftime bc_time; + } FTIME; + + if (0 == (retval = DOS_GETFTIME(handle, &FTIME.msc_time.date, + &FTIME.msc_time.time))) + { + *ftimep = FTIME.bc_time; + } + return retval; +} + +int _cdecl setftime (int handle, struct ftime *ftimep) +{ + union + { + struct + { + unsigned time; + unsigned date; + } msc_time; + struct ftime bc_time; + } FTIME; + + FTIME.bc_time = *ftimep; + + return DOS_SETFTIME(handle, FTIME.msc_time.date, FTIME.msc_time.time); +} + +#endif /* __TURBOC__ */ diff --git a/reference/C/CONTRIB/SNIP/ftime.h b/reference/C/CONTRIB/SNIP/ftime.h new file mode 100755 index 0000000..99c012c --- /dev/null +++ b/reference/C/CONTRIB/SNIP/ftime.h @@ -0,0 +1,20 @@ +/* +** Public domain by Jeff Dunlop +*/ + +#ifndef __TURBOC__ + +struct ftime /* As defined by Borland C */ +{ + unsigned ft_tsec : 5; /* Two second interval */ + unsigned ft_min : 6; /* Minutes */ + unsigned ft_hour : 5; /* Hours */ + unsigned ft_day : 5; /* Days */ + unsigned ft_month : 4; /* Months */ + unsigned ft_year : 7; /* Year */ +}; + +int _cdecl getftime (int, struct ftime *); +int _cdecl setftime (int, struct ftime *); + +#endif /* __TURBOC__ */ diff --git a/reference/C/CONTRIB/SNIP/getcmt.c b/reference/C/CONTRIB/SNIP/getcmt.c new file mode 100755 index 0000000..23651a7 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/getcmt.c @@ -0,0 +1,267 @@ +/* getcmt.c - get comments from a C or C++ source file */ +/* + Byte_Magic Software + 9850 Meadowglen Ln. #35 + Houston, Tx. 77042 + (713) 975-9033 + +Author: Greg Messer +Program: getcmt.c +Purpose: Isolate comments from a C or C++ source file. Filter. +Syntax: getcmt [/L?] [filename] + (may use redirection for file and/or device I/O) +Release: Released to the Public Domain by Byte_Magic Software. +Date: 07-11-88 GM... + First release. +Revised: 01-13-90 GM... + Streamlined logic. + 01-15-90 Bob Stout (RBS)... + Fixed unsigned char error as return from getc(). + 01-22-90 GM... + Fixed bug handling "xx/" (xx = **) at end of comment. + Added C++ comment extraction. + Added return of count to OS (ERRORLEVEL in MS-DOS). + 01-24-90 RBS + Added filename spec option + Added /? switch +System: Compiled with Zortech C V2.06 under MS-DOS 3.20 + for IBM PCs and compatibles. +Rules: ANSI C comments begin with /x and end with x/. (x = *). + Comments do not nest and do not appear in string or character + constants. + C++ comments begin with double slashes and end at EOL. + A Microsoft extension to C allows C++ style comments to serve as + single-line comments in C source. +Comments: Useful for creating documentation and improving commenting style. + Input may be from a specified filename or stdin. + Output is to stdout, so use DOS redirection for output. + Messages go to stderr so they are not redirectable from the screen. + Returns ERRORLEVEL = number of comments in source file(s). +Examples: + Example... Output to screen: + getcmt < cfile.c + (displays comments from cfile.c on screen) + type cfile.c | getcmt + (same as above but slightly slower) + getcmt < cfile.c | more + (same as above, but pauses after each full screen) + getcmt cfile.c /l | more + (same as above, but display line numbers) + + Example... Output to printer: + getcmt < cfile.c > prn + (same as above but prints output on printer) + type cfile.c | getcmt > prn + (same as above but slightly slower) + + Example... Output to file: + getcmt < cfile.c > cfile.cmt + (writes cfile.c comments to cfile.cmt, overwriting existing file) + getcmt < cfile.c >> cfile.doc + (writes cfile.c comments to end of cfile.doc (appends)) + + getcmt /? + (displays help screen, returns ERRORLEVEL = 0) + getcmt /x + (invalid option - displays help screen, returns ERRORLEVEL = -1) + + For complete instructions on using redirection symbols, consult + the PC-DOS or MS-DOS manual or a general DOS reference book. +*/ + +#include +#include +#include +#include + +#define LOOKS_GREAT 1 +#define LESS_FILLING 0 + +int extract_c_cmts(void); +void inside_c_cmt(int); + +FILE *infile = stdin; /* read input from here */ +int show_nos = 0; /* 0 = don't display line numbers */ +int line_no = 1; /* line_no = line number */ + +/* * * * * * * * * * * * * * * * * * * */ + +main(int argc, char *argv[]) /* main logic: */ +{ + register int i; + const char *hype = + "\nGETCMT v1.1 - GET CoMmenTs\nby Byte_Magic Software\n"; + const char *help = + "\nUsage: GETCMT [/l?] [filename | destination file or device]\n" + "Options: l - Print line numbers\n" + " ? - Help\n" + "\nFilename optional - Reads source code from stdin " + "(Ctrl-C to quit before EOF)\n"; + const char *oops = + "\a*** GETCMT - Can't open input file "; + /* display messages to operator */ +#if LOOKS_GREAT + fputs(hype, stderr); +#elif LESS_FILLING + i = 0; + while(hype[i] != '\0') + putc(hype[i++], stderr); +#endif + + if (1 < argc) + { + for (i = 1; i < argc; ++i) + { + if ('/' == *argv[i]) + { + if ('l' == tolower(argv[i][1])) + show_nos = 1; + else + { + int ercode; + + ercode = ('?' == argv[i][1]) ? 0 : -1; +#if LOOKS_GREAT + fputs(help, stderr); +#elif LESS_FILLING + i = 0; + while(help[i] != '\0') + putc(help[i++], stderr); +#endif + if (ercode) /* output BEL if invalid seitch */ + putc('\a', stderr); + return(ercode); + } + } + else + { + infile = fopen(argv[i], "r"); + if (!infile) + { +#if LOOKS_GREAT + fputs(oops, stderr); + fputs(argv[i], stderr); +#elif LESS_FILLING + char *p = argv[i]; + + i = 0; + while (oops[i]) + putc(oops[i], stderr); + i = 0; + while (*p) + putc(*p++, stderr); +#endif + } + } + } + } + + i = extract_c_cmts(); /* extract comments in infile */ + putc('\n', stdout); + + return(i); /* return number of comments to */ + /* OS (ERRORLEVEL in DOS) */ +} + +/* * * * * * * * * * * * * * * * * * * */ + +int extract_c_cmts() /* comment extraction logic: */ +{ + register int chi, cht; /* chi = char in, cht = char test */ + int count; /* count = comment count */ + + count = 0; + chi = getc(infile); + while(chi != EOF) /* as long as there is input... */ + { + if(chi == '/') /* process comments */ + { + cht = getc(infile); + if(cht == EOF) + return(count); + if(cht == '*' || cht == '/') /* if start of a comment... */ + { + count++; /* count it and */ + inside_c_cmt(cht); /* output all of the comment */ + } + else + ungetc(cht, infile); + } + if ('\n' == chi) + line_no += 1; + chi = getc(infile); /* continue scanning input */ + } + return(count); +} + +/* * * * * * * * * * * * * * * * * * * */ + +char *lntoaz(void) /* line number to zero-padded ASCII */ +{ + int i, num = line_no; + static char numbuf[] = "0000: "; + + if (9999 < num) + strncpy(numbuf, "0000", 4); + else for (i = 3; i >= 0; --i) + { + numbuf[i] = (char)('0' + num % 10); + num /= 10; + } + return numbuf; +} + +/* * * * * * * * * * * * * * * * * * * */ + +void inside_c_cmt(int ch) /* comment output logic: */ +{ /* input ch = either '*' for C */ + /* or '/' for C++ */ + + register int chi, cht; /* chi = char in, cht = char test */ +#if LESS_FILLING + char *p; +#endif + + if(ch == '/') /* make ch = '\n' if C++ */ + ch = '\n'; /* note: ch is already 1st char */ + /* of end comment if this is C */ + putc('\n', stdout); + if (show_nos) + { +#if LOOKS_GREAT + fputs(lntoaz(), stdout); +#elif LESS_FILLING + p = lntoaz(); + while (*p) + putc(*p++, stdout); +#endif + } + chi = getc(infile); + while(chi != EOF) /* as long as there is input... */ + { /* process comments */ + if(chi == ch) + { + if(ch == '\n') /* if C++ comment is ended... */ + return; /* stop outputting */ + cht = getc(infile); + if(cht == '/') /* if C comment is ended... */ + return; /* stop outputting */ + else + { + ungetc(cht, infile); + putc(chi, stdout); + } + } + else + putc(chi, stdout); /* else comment text, output it */ + if ('\n' == chi) + line_no += 1; + + chi = getc(infile); /* continue scanning input */ + } + return; +} + +/* * * * * * * * * * * * * * * * * * * */ +/* end of getcmt.c */ diff --git a/reference/C/CONTRIB/SNIP/getdcwd.c b/reference/C/CONTRIB/SNIP/getdcwd.c new file mode 100755 index 0000000..4b5ac6d --- /dev/null +++ b/reference/C/CONTRIB/SNIP/getdcwd.c @@ -0,0 +1,74 @@ +/* +** GETDCWD.C - returns the current working directory for a specific drive +** +** public domain by Bob Jarvis, modified by Bob Stout +*/ + +#if defined(__ZTC__) + #define GetDrive(d) dos_getdrive(&d) + #define FAR _far +#elif defined(__TURBOC__) + #define GetDrive(d) ((d) = getdisk() + 1) + #define FAR far +#else /* assume MSC */ + #define GetDrive(d) _dos_getdrive(&d) + #define FAR _far +#endif + +#include +#include +#include +#include + +char *getdcwd(unsigned int drive) /* 0 = current, 1 = A, 2 = B, etc */ +{ + union REGS regs; + struct SREGS sregs; + char *retptr; + + retptr = calloc(FILENAME_MAX + 4, sizeof(char)); + if(retptr == NULL) + return NULL; + + if(drive == 0) /* figure out which drive is current */ + { + GetDrive(drive); + drive += 1; + } + + *retptr = (char)((drive-1) + 'A'); + *(retptr+1) = ':'; + *(retptr+2) = '\\'; + + segread(&sregs); + regs.h.ah = 0x47; + regs.h.dl = (unsigned char)drive; + sregs.ds = FP_SEG((void FAR *)retptr); + regs.x.si = FP_OFF((void FAR *)retptr) + 3; + + intdosx(®s, ®s, &sregs); + if (15 == regs.x.ax) /* drive number invalid */ + { + free(retptr); + return NULL; + } + else return retptr; +} + +#ifdef TEST + +void main(int argc, char *argv[]) +{ + char *curpath; + unsigned int n; + + if(argc > 1) + n = (tolower(*argv[1]) - 'a') + 1; + else GetDrive(n); + + printf("curpath = '%s'\n", curpath = getdcwd(n)); + if (curpath) + free(curpath); +} + +#endif diff --git a/reference/C/CONTRIB/SNIP/getkey.c b/reference/C/CONTRIB/SNIP/getkey.c new file mode 100755 index 0000000..65bf913 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/getkey.c @@ -0,0 +1,27 @@ +/* +** Originally published as part of the MicroFirm Function Library +** +** Copyright 1986, S.E. Margison +** Copyright 1989-92, Robert B.Stout +** +** Subset version released to the public domain, 1990 +*/ + +#include + +int getkey(void) +{ + int i; + + switch (i = (int)getch()) + { + case 0xe0: +#ifdef MSDOS + return i; +#endif + case 0: + return 256 + (int)getch(); + default: + return i; + } +} diff --git a/reference/C/CONTRIB/SNIP/getopt3.c b/reference/C/CONTRIB/SNIP/getopt3.c new file mode 100755 index 0000000..c1d3c57 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/getopt3.c @@ -0,0 +1,102 @@ +/* + * * @(#)getopt.c 2.3 (smail) 5/30/87 + */ + +/* + * Here's something you've all been waiting for: the AT&T public domain + * source for getopt(3). It is the code which was given out at the 1985 + * UNIFORUM conference in Dallas. I obtained it by electronic mail directly + * from AT&T. The people there assure me that it is indeed in the public + * domain. + * + * There is no manual page. That is because the one they gave out at UNIFORUM + * was slightly different from the current System V Release 2 manual page. + * The difference apparently involved a note about the famous rules 5 and 6, + * recommending using white space between an option and its first argument, + * and not grouping options that have arguments. Getopt itself is currently + * lenient about both of these things White space is allowed, but not + * mandatory, and the last option in a group can have an argument. That + * particular version of the man page evidently has no official existence, + * and my source at AT&T did not send a copy. The current SVR2 man page + * reflects the actual behavor of this getopt. However, I am not about to + * post a copy of anything licensed by AT&T. + */ + +#ifdef BSD + #include +#else + #define index strchr + #include +#endif + +/* LINTLIBRARY */ + +#define NULL 0 +#define EOF (-1) +#define ERR(s, c) if(opterr){\ + extern int write(int, void *, unsigned);\ + char errbuf[2];\ + errbuf[0] = (char)c; errbuf[1] = '\n';\ + (void) write(2, strlwr(argv[0]), (unsigned)strlen(argv[0]));\ + (void) write(2, s, (unsigned)strlen(s));\ + (void) write(2, errbuf, 2);} + +extern char *index(); + +int opterr = 1; +int optind = 1; +int optopt; +char *optarg; + +int getopt(int argc, char *argv[], char *opts) +{ + static int sp = 1; + register int c; + register char *cp; + + if (sp == 1) + { + if (optind >= argc || argv[optind][0] != '-' || + argv[optind][1] == '\0') + return (EOF); + else if (strcmp(argv[optind], "--") == NULL) + { + optind++; + return (EOF); + } + } + optopt = c = argv[optind][sp]; + if (c == ':' || (cp = index(opts, c)) == NULL) + { + ERR(": illegal option -- ", c); + if (argv[optind][++sp] == '\0') + { + optind++; + sp = 1; + } + return ('?'); + } + if (*++cp == ':') + { + if (argv[optind][sp + 1] != '\0') + optarg = &argv[optind++][sp + 1]; + else if (++optind >= argc) + { + ERR(": option requires an argument -- ", c); + sp = 1; + return ('?'); + } + else optarg = argv[optind++]; + sp = 1; + } + else + { + if (argv[optind][++sp] == '\0') + { + sp = 1; + optind++; + } + optarg = NULL; + } + return (c); +} diff --git a/reference/C/CONTRIB/SNIP/getopts.c b/reference/C/CONTRIB/SNIP/getopts.c new file mode 100755 index 0000000..92c2d32 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/getopts.c @@ -0,0 +1,193 @@ +/* +** GETOPTS.C - Universal command line options parser +** +** Original Copyright 1993 by Bob Stout as part of +** the MicroFirm Function Library (MFL) +** +** This subset version is hereby donated to the public domain. +*/ + +#include +#include +#include +#include "portable.h" +#include "getopts.h" + +#define NUL '\0' +#define MAX_XARGS 512 + +int xargc; +char *xargv[MAX_XARGS]; + +/* +** getopts() +** +** Parameters: 1 - argc from main() +** 2 - argv from main() +** 3 - your program's options[] array +** +** Returns: Number of options specified or -1 if error +** +** Note: Your program should declare the global options[] array which +** specifies all options recognized by getopts(). +*/ + +int getopts(int argc, char *argv[]) +{ + int i, count, argidx = 0; + char *argp; + FILE *argfile; + char argline[256]; + struct Option_Tag *ptr; + + xargc = argc; + xargv[argidx++] = argv[0]; + for (i = 1, count = 0; i < argc; ++i) + { + if (strchr("-/", argv[i][0]) && !strchr("-/", argv[i][1])) + { + /* + ** Found a switch - If the 2nd character is also a switch + ** character. If so, then it's a literal and is skipped + */ + + if (strchr("-/", argv[i][1])) + continue; + + for (ptr = options; ptr->buf; ++ptr) + { + if ((int)argv[i][1] == ptr->letter) switch (ptr->type) + { + case Boolean_Tag: + if ('-' == argv[i][2]) + *((Boolean_T *)(ptr->buf)) = FALSE; + else *((Boolean_T *)(ptr->buf)) = TRUE; + ++count; + --xargc; + break; + + case Word_Tag: + sscanf(&argv[i][2], "%hd", (short *)(ptr->buf)); + ++count; + --xargc; + break; + + case DWord_Tag: + sscanf(&argv[i][2], "%ld", (long *)(ptr->buf)); + ++count; + --xargc; + break; + + case Double_Tag: + sscanf(&argv[i][2], "%lg", (double *)(ptr->buf); + ++count; + --xargc; + break; + + case String_Tag: + strcpy(ptr->buf, &argv[i][2]); + ++count; + --xargc; + break; + + default: + return ERROR; + } + } + } + else /* It must be a file name */ + { + DOSFileData ffblk; + + /* Set argp to point to the filename */ + + if (strchr("-/", argv[i][0])) + argp = &argv[i][1]; + else argp = argv[i]; + + /* If no wildcards, just copy it */ + + if (!strchr(argp, '*') && !strchr(argp, '?')) + { + xargv[argidx++] = argp; + continue; + } + + /* Expand wildcards, if possible */ + + if (0 == FIND_FIRST(argp, 0xff, &ffblk)) + { + char path[FILENAME_MAX], *p; + + /* Save the path for re-attachment */ + + if (NULL == (p = strrchr(argp, '\\'))) + p = strrchr(argp, '/'); + if (p) + { + char ch = *p; + + *p = NUL; + strcat(strcpy(path, argp), "\\"); + *p = ch; + } + else *path = NUL; + --xargc; + do + { + xargv[argidx] = malloc(strlen(ffblk.name) + + strlen(path) + 2); + strcat(strcpy(xargv[argidx], path), ffblk.name); + ++argidx; + ++xargc; + + } while (0 == FIND_NEXT(&ffblk)); + } + } + } + return count; +} + +#ifdef TEST + +#include + +Boolean_T test1 = TRUE, test2 = FALSE; +int test3 = -37; +long test4 = 100000L; +char test5[80] = "Default string"; + +struct Option_Tag options[] = { + {'A', Boolean_Tag, &test1 }, /* Valid options */ + {'B', Boolean_Tag, &test2 }, + {'C', Word_Tag, &test3 }, + {'D', DWord_Tag, &test4 }, + {'E', String_Tag, test5 }, + {'\0', ERROR, NULL } /* Terminating record */ +}; + +#define TFprint(v) ((v) ? "TRUE" : "FALSE") + +int main(int argc, char *argv[]) +{ + int i; + + printf("Defaults:\ntest1 = %s\ntest2 = %s\ntest3 = %d\ntest4 = %ld\n" + "test5 = \"%s\"\n\n", TFprint(test1), TFprint(test2), test3, + test4, test5); + + printf("getopts() returned %d\n", getopts(argc, argv)); + + printf("Options are now:\ntest1 = %s\ntest2 = %s\ntest3 = %d\n" + "test4 = %ld\ntest5 = \"%s\"\n\n", TFprint(test1), + TFprint(test2), test3, test4, test5); + + puts("Hit any key to continue"); + getch(); + for (i = 0; i < xargc; ++i) + printf("xargv[%d] = \"%s\"\n", i, xargv[i]); + printf("\nxargc = %d\n", xargc); + return 0; +} + +#endif diff --git a/reference/C/CONTRIB/SNIP/getopts.h b/reference/C/CONTRIB/SNIP/getopts.h new file mode 100755 index 0000000..d3d0d80 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/getopts.h @@ -0,0 +1,31 @@ +/* +** GETOPTS.H +** +** public domain by Bob Stout +*/ + +#undef ERROR +#undef FALSE +#undef TRUE + +typedef enum {ERROR = -1,FALSE, TRUE} Boolean_T; + +typedef enum { + Boolean_Tag, + Word_Tag, + DWord_Tag, + Double_Tag, + String_Tag + } TAG_TYPE; + +struct Option_Tag { + int letter; /* Option switch */ + TAG_TYPE type; /* Type of option */ + void *buf; /* Storage location */ +}; + +extern struct Option_Tag options[]; +extern int xargc; +extern char *xargv[]; + +int getopts(int, char *[]); diff --git a/reference/C/CONTRIB/SNIP/getseg.c b/reference/C/CONTRIB/SNIP/getseg.c new file mode 100755 index 0000000..ff35e5e --- /dev/null +++ b/reference/C/CONTRIB/SNIP/getseg.c @@ -0,0 +1,49 @@ +/* +** GETSEG.C - How to get the memory segment of an object +** +** public domain demo by Bob Stout +*/ + +#include +#include + +#ifdef __TURBOC__ + #define FAR far +#else + #define FAR _far +#endif + +#define GetSeg(obj) (unsigned)((unsigned long)(((void FAR *)(obj))) >> 16) +#define GetOfs(obj) (unsigned)((unsigned long)(((void FAR *)(obj))) & 0xffff) + +int dummyv = 0; + +int dummyf(void) +{ + return dummyv; +} + +void main(void) +{ + struct SREGS sregs; + + segread (&sregs); + printf("DS = %04X, CS = %04X\n", sregs.ds, sregs.cs); + +#if defined(__ZTC__) + printf("&dummyv = %lp, dummyf = %lp\n\n", +#else + printf("&dummyv = %Fp, dummyf = %Fp\n\n", +#endif + +#if defined(__ZTC__) || defined(__TURBOC__) + (int FAR *)&dummyv, (int (FAR *)())dummyf); +#else /* MSC doesn't allow casting near function pointers to far */ + (int FAR *)&dummyv, dummyf); +#endif + + printf("GetSeg(dummyv) = %04X, GetSeg(dummyf) = %04X\n", + GetSeg(&dummyv), GetSeg(dummyf)); + printf("GetOfs(dummyv) = %04X, GetOfs(dummyf) = %04X\n", + GetOfs(&dummyv), GetOfs(dummyf)); +} diff --git a/reference/C/CONTRIB/SNIP/getstrng.c b/reference/C/CONTRIB/SNIP/getstrng.c new file mode 100755 index 0000000..ee6178a --- /dev/null +++ b/reference/C/CONTRIB/SNIP/getstrng.c @@ -0,0 +1,66 @@ +/* +** GETSTRNG.C -- Demonstation of dynamic memory allocation to +** receive string of unknown length. +** +** Ron Sires 1/31/89, released to the public domain. +** Bob Stout 2/18/93, modified to use a static buffer +*/ + +#include +#include + +#define BLOCKSIZ 16 + +char *getstring(void) +{ + int newchar; + size_t i; + static size_t bufsize = 0; + static char *buffer = NULL; + + /* Get chars from keyboard and put them in buffer. */ + + for (i = 0; ((newchar = getchar()) != EOF) && (newchar != '\n') + && (newchar != '\r'); ++i ) + { + if (i + 1 > bufsize) + { + /* If buffer is full, resize it. */ + + if (NULL == (buffer = realloc(buffer, bufsize + BLOCKSIZ))) + { + puts("\agetstrng() - Insufficient memory"); + + /* Add terminator to partial string */ + + if (buffer) + buffer[i] = '\0'; + return buffer; + } + bufsize += BLOCKSIZ; + } + buffer[i] = (char) newchar; + } + buffer[i] = '\0'; /* Tack on a null-terminator. */ + return buffer; +} + +#ifdef TEST + +#include + +int main(void) +{ + char *string; + + puts("Enter strings of any length or to quit\n"); + do + { + string = getstring(); + printf("You entered:\n\"%s\"\n\n", string); + } while (strlen(string)); + free(string); + return EXIT_SUCCESS; +} + +#endif /* TEST */ diff --git a/reference/C/CONTRIB/SNIP/getvol.c b/reference/C/CONTRIB/SNIP/getvol.c new file mode 100755 index 0000000..6321fde --- /dev/null +++ b/reference/C/CONTRIB/SNIP/getvol.c @@ -0,0 +1,68 @@ +/* +** GETVOL.C - Retrieve a disk volume label +** (proof you don't need FCBs to do it!) +** +** public domain demo by Bob Stout +*/ + +#include +#include +#include +#include +#include + +#if defined(__TURBOC__) + #pragma option -a- + #include + #define _dos_findfirst(f,a,b) findfirst(f,b,a) + #define _dos_findnext(b) findnext(b) + #define find_t ffblk + #define _A_VOLID FA_LABEL + #define attrib ff_attrib + #define name ff_name +#else + #include + #if defined(__ZTC__) + #pragma ZTC align 1 + #else /* MSC/QC/WATCOM/METAWARE */ + #pragma pack(1) + #endif +#endif + +#define SUCCESS 0 + +char *getvol(char drive) +{ + char search[] = "A:\\*.*"; + static struct find_t ff; + + *search = drive; + if (SUCCESS == _dos_findfirst(search, _A_VOLID, &ff)) + { + if (8 < strlen(ff.name)) /* Eliminate period */ + strcpy(&ff.name[8], &ff.name[9]); + return ff.name; + } + else return NULL; +} + +#ifdef TEST + +int main(int argc, char *argv[]) +{ + char *label; + + if (2 > argc) + { + puts("\aUsage: GETVOL d[:]"); + puts("where: d = drive letter (e.g. A, B, C, etc."); + return -1; + } + if (NULL == (label = getvol(*argv[1]))) + printf("Unable to read a label on drive %c:\n", *argv[1]); + else printf("The volume label of drive %c: is \"%s\"\n", + *argv[1], label); + return 0; +} + +#endif diff --git a/reference/C/CONTRIB/SNIP/glbl_env.c b/reference/C/CONTRIB/SNIP/glbl_env.c new file mode 100755 index 0000000..9699aae --- /dev/null +++ b/reference/C/CONTRIB/SNIP/glbl_env.c @@ -0,0 +1,364 @@ +/***************************************************************************** + This code is based upon the program SETPATH.PAS (located in BPROGA) by + David Dubois [71401,747] + + This Turbo C version is written by Peter Thomas [75716,2377] + + This series of routines are designed to Locate, Retrieve, Update, and + Remove "Variables" from the MASTER copy of the DOS Environment table. + The routines have been written in a manner that avoids linking any + EXTERNAL routines for string manipulation, and thus should be independent + of memory model being used. + + Be careful that changes made to the Environment with these routines + ONLY OCCUR IN THE MASTER COPY, and that if COMMAND.COM is spawned + from a routine that has changed the environment, NO CHANGES WILL BE + SEEN IN THE ENVIRONMENT. This is most apparent when this program is run + in the INTEGRATED environment: changes made by this technique will + not appear if the "OS Shell" is invoked, and will only appear on exit + from TC. + + For full documentation on the techniques used here can be found in the + file COMENV.ARC located in LIB 2 of BPROGA on Compuserve. + + As David Dubois says: + + I hereby dedicate this knowledge to the public domain. Feel free to use + it, but if you do, please mention my name. There are no guarantees, and + in fact, I wouldn't bet a dollar that it will work every time. + + That this works at all is based on experimental, rather than properly + documented, evidence. There are no guarantees. But then, its free. + +*****************************************************************************/ + +#include +#include + +#ifdef __ZTC__ + #error ZTC/C++ not supported - huge pointers required! +#endif + +#ifdef __TURBOC__ + #include + #define Fmalloc farmalloc + #define Ffree farfree +#else + #include + #include + #define far _far + #define Fmalloc _fmalloc + #define Ffree _ffree + #define MK_FP(seg,offset) \ + ((void far *)(((unsigned long)(seg)<<16) | (unsigned)(offset))) +#endif + +/* + * Mstr_FindEnvironment: + * Scans for the "Master" Environment area, and returns + * a pointer to it, and the size of the environment. +*/ +void Mstr_FindEnvironment ( char far **Env , unsigned *EnvSize ) +{ + unsigned int far *CommandSeg, far *TempSeg ; + char far *BlockSeg ; + + /* + * Scan through PSP's looking for a block that is its own father. + * This block is the PSP of COMMAND.COM + */ + TempSeg = MK_FP ( _psp , 0 ) ; + do + { + CommandSeg = TempSeg ; + TempSeg = MK_FP ( *(TempSeg+8) , 0 ) ; + } + while ( TempSeg != CommandSeg ) ; + + /* + * Scan forward through memory looking for the correct MSB. + * This will have COMMAND.COM's PSP as owner, and begin with + * the character M + */ + BlockSeg = (char far *)CommandSeg ; + do + { + BlockSeg = MK_FP ( FP_SEG(BlockSeg)+1 , 0 ) ; + } + while ( ( *(unsigned int far *)(BlockSeg+1) != FP_SEG ( CommandSeg ) ) || + ( *BlockSeg != 'M' ) ) ; + + /* + * The environment is the NEXT segment of memory + * and bytes 4 and 5 are the size in paragraphs + */ + *Env = MK_FP ( FP_SEG(BlockSeg)+1 , 0 ) ; + *EnvSize = 16 * *(unsigned int far *)(BlockSeg+3) ; +} + +/* + * Mstr_getenv: + * Scans the "Master" Environment for a given "sub string" + * and returns a pointer to it. + * Similar to Turbo routine "getenv" but uses the Master copy of the + * environment table. +*/ +char far *Mstr_getenv (char far *Env , char far *name) +{ + char far *Sub_Env, far *str1, far *str2 ; + + /* + * Start at the beginning of the environment + */ + Sub_Env = Env ; + + /* + * While the "sub string" we're looking at is non-zero + */ + for ( ; *Sub_Env ; ) + { + /* + * Simulate a "strcmp" on the "sub string" of the environment + * and the string we're looking for + */ + for ( str1 = Sub_Env , str2 = name ; + (*str1) && (*str2) && ( *str1 == *str2) ; + str1++ , str2++ ) ; + /* + * If we reached the end of the string we're looing for + * we've found the correct portion of the environment. + * Return the ptr to the start of this "sub string" + */ + if ( !*str2 ) + return ( Sub_Env ) ; + + /* + * Otherwise, advance to the next "sub string" in the environment + * by performing a "strchr" function + */ + for ( ; *(Sub_Env++) ; ) ; + } + + /* + * Obviously, the string is not present in the environment. + * Return this fact. + */ + return ( NULL ) ; +} + +/* + * Mstr_delenv: + * Scans the "Master" Environment for a given "sub string" + * and removes it. +*/ +int Mstr_delenv (char far *Env , unsigned EnvSize , char far *name) +{ + char far *Sub_Env , far *New_Env ; + char huge *Dest , far *Src , huge *End_Env ; + + int Done ; + unsigned Ctr ; + + /* + * Allocate a chunk of storage to act as a "working" copy of + * the Environment table + */ + New_Env = Fmalloc ( EnvSize ) ; + + /* + * Copy the data from the Master to Working copy of the + * Environment table. + * Simulates a "memcpy" function. + */ + for ( Src = Env , Dest = (char far *)New_Env , Ctr = 0 ; + Ctr < EnvSize ; + *(Dest++) = *(Src++) , Ctr++ ) ; + + /* + * Scan the working copy of the environment for the desired + * sub string + */ + Sub_Env = Mstr_getenv ( New_Env , name ) ; + + if ( Sub_Env == NULL ) + { + /* + * If not found, do nothing + */ + Done = -1 ; + } else { + /* + * Locate the end of the string to delete + * Simulate a "strchr" call + */ + for ( Src = Sub_Env ; *(Src++) ; ) ; + + /* + * Move the rest of the environment back over the "sub string" + * being deleted. + * Simulated "memcpy" function. + * Huge pointers used for pointer comparison purposes. + */ + for ( Dest = (char huge *)Sub_Env , End_Env = (char huge *) (New_Env + EnvSize ) ; + ( Dest < End_Env ) ; + *(Dest++) = *(Src++) ) ; + + /* + * Copy the data from the Working to Master copy of the + * Environment table. + * Simulates a "memcpy" function. + */ + for ( Src = New_Env , Dest = (char huge *)Env , Ctr = 0 ; + Ctr < EnvSize ; + *(Dest++) = *(Src++) , Ctr++ ) ; + + /* + * Signal all done + */ + Done = 0 ; + } + + /* + * Free all working storage + */ + Ffree ( New_Env ) ; + + return ( Done ) ; +} + +/* + * Mstr_putenv: + * Adds/Replaces a given "sub string" in the Master Environment. + * Similar to Turbo routine "putenv" but uses the Master copy of the + * environment table. +*/ +int Mstr_putenv (char far *Env , unsigned EnvSize , char far *name ) +{ + char far *Sub_Env , far *Temp_Name ; + char huge *Dest , far *Src , huge *End_Env ; + int Done ; + + /* + * Allocate a chunk of storage to create the Variable name to add + * to the Environment table + */ + Temp_Name = Fmalloc ( 256 ) ; + + /* + * Extract only the Name portion of the data to add to the Environment + */ + for ( Src = name , Dest = Temp_Name ; + *Src && ( *Src != '=' ) ; + *(Dest++) = *(Src++) ) ; + + /* + * Ensure that the resulting name is well formed. + */ + *(Dest++) = '=' ; + *Dest = 0 ; + + /* + * Delete this sub string if found in the environment + */ + Mstr_delenv ( Env , EnvSize , Temp_Name ) ; + + /* + * Locate the END of the Master table by locating a zero length + * String in it + */ + Sub_Env = Env ; + for ( ; *Sub_Env ; ) + { + for ( ; *(Sub_Env++) ; ) ; + } + + /* + * Add the new string to the END of the existing environment, with + * trincation IF needed + */ + for ( Dest = (char huge *)(Sub_Env) , Src = name , End_Env = (char huge *) (Env + EnvSize ) ; + ( Dest < End_Env ) && (*Src) ; + *(Dest++) = *(Src++) ) ; + + Done = -1 ; + if ( !*Src ) + { + /* + * If the string to add was FULLY added, ensure that the + * newly updated environment is properly finished + */ + Done = 0 ; + *(Dest++) = 0 ; + *Dest = 0 ; + } + + /* + * As a real safety measure, ensure that the FINAL two bytes of the + * Environment are both 0. This will finish the last string AND + * ensure that a zero length string is also present + */ + *(End_Env-1) = 0 ; + *(End_Env-2) = 0 ; + + /* + * Free all working storage + */ + Ffree ( Temp_Name ) ; + + return ( Done ) ; +} + +void main(void) +{ + char far *Env ; + unsigned EnvSize ; + + /* + * Locate the Master Table + */ + Mstr_FindEnvironment ( &Env, &EnvSize ) ; + + /* + * Describe what we've just found + */ + printf ( "Env = %Fp Size = %u\n\n" , Env , EnvSize ) ; + + /* + * Search for, and display LOCATIONS of PATH, FRED and BERT + */ + printf ( "Search for PATH= returns %Fp\n", Mstr_getenv ( Env , "PATH=" ) ) ; + printf ( "Search for FRED= returns %Fp\n", Mstr_getenv ( Env , "FRED=" ) ) ; + printf ( "Search for BERT= returns %Fp\n", Mstr_getenv ( Env , "BERT=" ) ) ; + + /* + * Add FRED and BERT to the environment + */ + Mstr_putenv ( Env , EnvSize , "FRED=fred" ) ; + Mstr_putenv ( Env , EnvSize , "BERT=bert" ) ; + + printf ( "\nAdded FRED and BERT to environment\n" ) ; + + /* + * Search for, and display LOCATIONS of PATH ,FRED and BERT + */ + printf ( "Search for PATH= returns %Fp\n", Mstr_getenv ( Env , "PATH=" ) ) ; + printf ( "Search for FRED= returns %Fp\n", Mstr_getenv ( Env , "FRED=" ) ) ; + printf ( "Search for BERT= returns %Fp\n", Mstr_getenv ( Env , "BERT=" ) ) ; + + /* + * Delete FRED from the environment + */ + Mstr_delenv ( Env , EnvSize , "FRED=" ) ; + + printf ( "\nDeleted FRED= from the environment\n" ) ; + + /* + * Search for, and display LOCATIONS of PATH, FRED, and BERT + */ + printf ( "Search for PATH= returns %Fp\n", Mstr_getenv ( Env , "PATH=" ) ) ; + printf ( "Search for FRED= returns %Fp\n", Mstr_getenv ( Env , "FRED=" ) ) ; + printf ( "Search for BERT= returns %Fp\n", Mstr_getenv ( Env , "BERT=" ) ) ; + + printf ( "\nIssue the DOS command SET and see that BERT is now set\n" ) ; + +} diff --git a/reference/C/CONTRIB/SNIP/grafline.c b/reference/C/CONTRIB/SNIP/grafline.c new file mode 100755 index 0000000..b05c1e5 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/grafline.c @@ -0,0 +1,29 @@ +/* +** Demonstration of PC line drawing characters by David Harmon +*/ + +#include + +void main(void) +{ + /* compile and run this on a PC, and meditate on the results. */ + + puts("ASCII Decimal Hex ASCII Dec Hex\n" + "----- ----------- -------- ----- --- ---\n" + "\332 \302 \277 218 194 191 da c2 bf \304 196 c4\n" + "\303 \305 \264 195 197 180 c3 c5 b4 \263 179 b3\n" + "\300 \301 \331 192 193 217 c0 c1 d9 \315 205 cd\n" + " \272 186 ba\n" + "\311 \313 \273 201 203 187 c9 cb bb\n" + "\314 \316 \271 204 206 185 cc ce b9 \260 176 b0\n" + "\310 \312 \274 200 202 188 c8 ca bc \261 177 b1\n" + " \262 178 b2\n" + "\326 \322 \267 214 210 183 d6 d2 b7 \333 219 db\n" + "\307 \327 \266 199 215 182 c7 d7 b6\n" + "\323 \320 \275 211 208 189 d3 d0 bd \334 220 dc\n" + " \335 221 dd\n" + "\325 \321 \270 213 209 184 d5 d1 b8 \336 222 de\n" + "\306 \330 \265 198 216 181 c6 d8 b5 \337 223 df\n" + "\324 \317 \276 212 207 190 d4 cf be\n" + ); +} diff --git a/reference/C/CONTRIB/SNIP/grep.c b/reference/C/CONTRIB/SNIP/grep.c new file mode 100755 index 0000000..708434f --- /dev/null +++ b/reference/C/CONTRIB/SNIP/grep.c @@ -0,0 +1,567 @@ +/* + * The information in this document is subject to change + * without notice and should not be construed as a commitment + * by Digital Equipment Corporation or by DECUS. + * + * Neither Digital Equipment Corporation, DECUS, nor the authors + * assume any responsibility for the use or reliability of this + * document or the described software. + * + * Copyright (C) 1980, DECUS + * + * General permission to copy or modify, but not for profit, is + * hereby granted, provided that the above copyright notice is + * included and reference made to the fact that reproduction + * privileges were granted by DECUS. + */ +#include + +/* + * grep + * + * Runs on the Decus compiler or on vms, On vms, define as: + * grep :== "$disk:[account]grep" (native) + * grep :== "$disk:[account]grep grep" (Decus) + * See below for more information. + */ + +char *documentation[] = { +"grep searches a file for a given pattern. Execute by", +" grep [flags] regular_expression file_list\n", +"Flags are single characters preceeded by '-':", +" -c Only a count of matching lines is printed", +" -f Print file name for matching lines switch, see below", +" -n Each line is preceeded by its line number", +" -v Only print non-matching lines\n", +"The file_list is a list of files (wildcards are acceptable on RSX modes).", +"\nThe file name is normally printed if there is a file given.", +"The -f flag reverses this action (print name no file, not if more).\n", +0 }; + +char *patdoc[] = { +"The regular_expression defines the pattern to search for. Upper- and", +"lower-case are always ignored. Blank lines never match. The expression", +"should be quoted to prevent file-name translation.", +"x An ordinary character (not mentioned below) matches that character.", +"'\\' The backslash quotes any character. \"\\$\" matches a dollar-sign.", +"'^' A circumflex at the beginning of an expression matches the", +" beginning of a line.", +"'$' A dollar-sign at the end of an expression matches the end of a line.", +"'.' A period matches any character except \"new-line\".", +"':a' A colon matches a class of characters described by the following", +"':d' character. \":a\" matches any alphabetic, \":d\" matches digits,", +"':n' \":n\" matches alphanumerics, \": \" matches spaces, tabs, and", +"': ' other control characters, such as new-line.", +"'*' An expression followed by an asterisk matches zero or more", +" occurrances of that expression: \"fo*\" matches \"f\", \"fo\"", +" \"foo\", etc.", +"'+' An expression followed by a plus sign matches one or more", +" occurrances of that expression: \"fo+\" matches \"fo\", etc.", +"'-' An expression followed by a minus sign optionally matches", +" the expression.", +"'[]' A string enclosed in square brackets matches any character in", +" that string, but no others. If the first character in the", +" string is a circumflex, the expression matches any character", +" except \"new-line\" and the characters in the string. For", +" example, \"[xyz]\" matches \"xx\" and \"zyx\", while \"[^xyz]\"", +" matches \"abc\" but not \"axb\". A range of characters may be", +" specified by two characters separated by \"-\". Note that,", +" [a-z] matches alphabetics, while [z-a] never matches.", +"The concatenation of regular expressions is a regular expression.", +0}; + +#define LMAX 512 +#define PMAX 256 + +#define CHAR 1 +#define BOL 2 +#define EOL 3 +#define ANY 4 +#define CLASS 5 +#define NCLASS 6 +#define STAR 7 +#define PLUS 8 +#define MINUS 9 +#define ALPHA 10 +#define DIGIT 11 +#define NALPHA 12 +#define PUNCT 13 +#define RANGE 14 +#define ENDPAT 15 + +int cflag=0, fflag=0, nflag=0, vflag=0, nfile=0, debug=0; + +char *pp, lbuf[LMAX], pbuf[PMAX]; + +extern char *cclass(), *pmatch(); + + +/*** Main program - parse arguments & grep *************/ +main(argc, argv) +int argc; +char *argv[]; +{ + register char *p; + register int c, i; + int gotpattern; + + FILE *f; + + if (argc <= 1) + usage("No arguments"); + if (argc == 2 && argv[1][0] == '?' && argv[1][1] == 0) { + help(documentation); + help(patdoc); + return; + } + nfile = argc-1; + gotpattern = 0; + for (i=1; i < argc; ++i) { + p = argv[i]; + if (*p == '-') { + ++p; + while (c = *p++) { + switch(tolower(c)) { + + case '?': + help(documentation); + break; + + case 'C': + case 'c': + ++cflag; + break; + + case 'D': + case 'd': + ++debug; + break; + + case 'F': + case 'f': + ++fflag; + break; + + case 'n': + case 'N': + ++nflag; + break; + + case 'v': + case 'V': + ++vflag; + break; + + default: + usage("Unknown flag"); + } + } + argv[i] = 0; + --nfile; + } else if (!gotpattern) { + compile(p); + argv[i] = 0; + ++gotpattern; + --nfile; + } + } + if (!gotpattern) + usage("No pattern"); + if (nfile == 0) + grep(stdin, 0); + else { + fflag = fflag ^ (nfile > 0); + for (i=1; i < argc; ++i) { + if (p = argv[i]) { + if ((f=fopen(p, "r")) == NULL) + cant(p); + else { + grep(f, p); + fclose(f); + } + } + } + } +} + +/*** Display a file name *******************************/ +file(s) +char *s; +{ + printf("File %s:\n", s); +} + +/*** Report unopenable file ****************************/ +cant(s) +char *s; +{ + fprintf(stderr, "%s: cannot open\n", s); +} + +/*** Give good help ************************************/ +help(hp) +char **hp; +{ + register char **dp; + + for (dp = hp; *dp; ++dp) + printf("%s\n", *dp); +} + +/*** Display usage summary *****************************/ +usage(s) +char *s; +{ + fprintf(stderr, "?GREP-E-%s\n", s); + fprintf(stderr, + "Usage: grep [-cfnv] pattern [file ...]. grep ? for help\n"); + exit(1); +} + +/*** Compile the pattern into global pbuf[] ************/ +compile(source) +char *source; /* Pattern to compile */ +{ + register char *s; /* Source string pointer */ + register char *lp; /* Last pattern pointer */ + register int c; /* Current character */ + int o; /* Temp */ + char *spp; /* Save beginning of pattern */ + + s = source; + if (debug) + printf("Pattern = \"%s\"\n", s); + pp = pbuf; + while (c = *s++) { + /* + * STAR, PLUS and MINUS are special. + */ + if (c == '*' || c == '+' || c == '-') { + if (pp == pbuf || + (o=pp[-1]) == BOL || + o == EOL || + o == STAR || + o == PLUS || + o == MINUS) + badpat("Illegal occurrance op.", source, s); + store(ENDPAT); + store(ENDPAT); + spp = pp; /* Save pattern end */ + while (--pp > lp) /* Move pattern down */ + *pp = pp[-1]; /* one byte */ + *pp = (c == '*') ? STAR : + (c == '-') ? MINUS : PLUS; + pp = spp; /* Restore pattern end */ + continue; + } + /* + * All the rest. + */ + lp = pp; /* Remember start */ + switch(c) { + + case '^': + store(BOL); + break; + + case '$': + store(EOL); + break; + + case '.': + store(ANY); + break; + + case '[': + s = cclass(source, s); + break; + + case ':': + if (*s) { + switch(tolower(c = *s++)) { + + case 'a': + case 'A': + store(ALPHA); + break; + + case 'd': + case 'D': + store(DIGIT); + break; + + case 'n': + case 'N': + store(NALPHA); + break; + + case ' ': + store(PUNCT); + break; + + default: + badpat("Unknown : type", source, s); + + } + break; + } + else badpat("No : type", source, s); + + case '\\': + if (*s) + c = *s++; + + default: + store(CHAR); + store(tolower(c)); + } + } + store(ENDPAT); + store(0); /* Terminate string */ + if (debug) { + for (lp = pbuf; lp < pp;) { + if ((c = (*lp++ & 0377)) < ' ') + printf("\\%o ", c); + else printf("%c ", c); + } + printf("\n"); + } +} + +/*** Compile a class (within []) ***********************/ +char *cclass(source, src) +char *source; /* Pattern start -- for error msg. */ +char *src; /* Class start */ +{ + register char *s; /* Source pointer */ + register char *cp; /* Pattern start */ + register int c; /* Current character */ + int o; /* Temp */ + + s = src; + o = CLASS; + if (*s == '^') { + ++s; + o = NCLASS; + } + store(o); + cp = pp; + store(0); /* Byte count */ + while ((c = *s++) && c!=']') { + if (c == '\\') { /* Store quoted char */ + if ((c = *s++) == '\0') /* Gotta get something */ + badpat("Class terminates badly", source, s); + else store(tolower(c)); + } + else if (c == '-' && + (pp - cp) > 1 && *s != ']' && *s != '\0') { + c = pp[-1]; /* Range start */ + pp[-1] = RANGE; /* Range signal */ + store(c); /* Re-store start */ + c = *s++; /* Get end char and*/ + store(tolower(c)); /* Store it */ + } + else { + store(tolower(c)); /* Store normal char */ + } + } + if (c != ']') + badpat("Unterminated class", source, s); + if ((c = (pp - cp)) >= 256) + badpat("Class too large", source, s); + if (c == 0) + badpat("Empty class", source, s); + *cp = c; + return(s); +} + +/*** Store an entry in the pattern buffer **************/ +store(op) + int op; +{ + if (pp >= &pbuf[PMAX]) + error("Pattern too complex\n"); + *pp++ = op; +} + +/*** Report a bad pattern specification ****************/ +badpat(message, source, stop) +char *message; /* Error message */ +char *source; /* Pattern start */ +char *stop; /* Pattern end */ +{ + fprintf(stderr, "-GREP-E-%s, pattern is\"%s\"\n", message, source); + fprintf(stderr, "-GREP-E-Stopped at byte %d, '%c'\n", + stop-source, stop[-1]); + error("?GREP-E-Bad pattern\n"); +} + +/*** Scan the file for the pattern in pbuf[] ***********/ +grep(fp, fn) +FILE *fp; /* File to process */ +char *fn; /* File name (for -f option) */ +{ + register int lno, count, m; + + lno = 0; + count = 0; + while (fgets(lbuf, LMAX, fp)) { + ++lno; + m = match(); + if ((m && !vflag) || (!m && vflag)) { + ++count; + if (!cflag) { + if (fflag && fn) { + file(fn); + fn = 0; + } + if (nflag) + printf("%d\t", lno); + printf("%s\n", lbuf); + } + } + } + if (cflag) { + if (fflag && fn) + file(fn); + printf("%d\n", count); + } +} + +/*** Match line (lbuf) with pattern (pbuf) return 1 if match ***/ +match() +{ + register char *l; /* Line pointer */ + + for (l = lbuf; *l; ++l) { + if (pmatch(l, pbuf)) + return(1); + } + return(0); +} + +/*** Match partial line with pattern *******************/ +char *pmatch(line, pattern) +char *line; /* (partial) line to match */ +char *pattern; /* (partial) pattern to match */ +{ + register char *l; /* Current line pointer */ + register char *p; /* Current pattern pointer */ + register char c; /* Current character */ + char *e; /* End for STAR and PLUS match */ + int op; /* Pattern operation */ + int n; /* Class counter */ + char *are; /* Start of STAR match */ + + l = line; + if (debug > 1) + printf("pmatch(\"%s\")\n", line); + p = pattern; + while ((op = *p++) != ENDPAT) { + if (debug > 1) + printf("byte[%d] = 0%o, '%c', op = 0%o\n", + l-line, *l, *l, op); + switch(op) { + + case CHAR: + if (tolower(*l++) != *p++) + return(0); + break; + + case BOL: + if (l != lbuf) + return(0); + break; + + case EOL: + if (*l != '\0') + return(0); + break; + + case ANY: + if (*l++ == '\0') + return(0); + break; + + case DIGIT: + if ((c = *l++) < '0' || (c > '9')) + return(0); + break; + + case ALPHA: + c = tolower(*l++); + if (c < 'a' || c > 'z') + return(0); + break; + + case NALPHA: + c = tolower(*l++); + if (c >= 'a' && c <= 'z') + break; + else if (c < '0' || c > '9') + return(0); + break; + + case PUNCT: + c = *l++; + if (c == 0 || c > ' ') + return(0); + break; + + case CLASS: + case NCLASS: + c = tolower(*l++); + n = *p++ & 0377; + do { + if (*p == RANGE) { + p += 3; + n -= 2; + if (c >= p[-2] && c <= p[-1]) + break; + } + else if (c == *p++) + break; + } while (--n > 1); + if ((op == CLASS) == (n <= 1)) + return(0); + if (op == CLASS) + p += n - 2; + break; + + case MINUS: + e = pmatch(l, p); /* Look for a match */ + while (*p++ != ENDPAT); /* Skip over pattern */ + if (e) /* Got a match? */ + l = e; /* Yes, update string */ + break; /* Always succeeds */ + + case PLUS: /* One or more ... */ + if ((l = pmatch(l, p)) == 0) + return(0); /* Gotta have a match */ + case STAR: /* Zero or more ... */ + are = l; /* Remember line start */ + while (*l && (e = pmatch(l, p))) + l = e; /* Get longest match */ + while (*p++ != ENDPAT); /* Skip over pattern */ + while (l >= are) { /* Try to match rest */ + if (e = pmatch(l, p)) + return(e); + --l; /* Nope, try earlier */ + } + return(0); /* Nothing else worked */ + + default: + printf("Bad op code %d\n", op); + error("Cannot happen -- match\n"); + } + } + return(l); +} + +/*** Report an error ***********************************/ +error(s) +char *s; +{ + fprintf(stderr, "%s", s); + exit(1); +} diff --git a/reference/C/CONTRIB/SNIP/head.c b/reference/C/CONTRIB/SNIP/head.c new file mode 100755 index 0000000..a07e7f8 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/head.c @@ -0,0 +1,40 @@ +#include +#include +#include + +#define NUL '\000' +#define BEL '\007' +#define LINE_LEN 132 + +void give_up(char *msg) +{ + putchar(BEL); + puts(msg); + exit(-1); +} + +int main(int argc, char *argv[]) +{ + FILE *infile; + char line[LINE_LEN + 2]; /* Allow for '\n' & NUL */ + int i, N = 0; + + if (2 > argc) + give_up("Usage: HEAD file [number_of_lines]"); + if (NULL == (infile = fopen(argv[1], "r"))) + give_up("Unable to open input file"); + if (2 < argc) + N = atoi(argv[2]); + if (!N) N = 4; + for (i = 0; i < N; ++i) + { + if (NULL == fgets(line, LINE_LEN + 1, infile)) + break; + line[LINE_LEN + 1] = NUL; /* Allow too-long lines */ + fputs(line, stdout); + if (!strrchr(line, '\n')) + i -= 1; /* More to read */ + } + fclose(infile); + return EXIT_SUCCESS; +} diff --git a/reference/C/CONTRIB/SNIP/hexdump.c b/reference/C/CONTRIB/SNIP/hexdump.c new file mode 100755 index 0000000..bb90b7a --- /dev/null +++ b/reference/C/CONTRIB/SNIP/hexdump.c @@ -0,0 +1,88 @@ +/* +** HEXDUMP.C - Dump a file. +** +** This Program Written By Paul Edwards w/ modifications by Bob Stout +** Released to the public domain +*/ + +#include +#include +#include +#include + +static void dodump(FILE *fp, long start, long count); +static void skipb(FILE *fp, long start); + +main(int argc, char **argv) +{ + FILE *fp; + long start, count; + + if (argc < 2) + { + puts("Usage: HEXDUMP file_name [start] [length]"); + return (EXIT_FAILURE); + } + if (argc > 2) + start = atol(*(argv + 2)); + else start = 0L; + if (argc > 3) + count = atol(*(argv + 3)); + else count = -1L; + fp = fopen(*(argv + 1), "rb"); + if (fp == NULL) + { + printf("unable to open file %s for input\n", *(argv+1)); + return (EXIT_FAILURE); + } + skipb(fp, start); + dodump(fp, start, count); + return (EXIT_SUCCESS); +} + +static void dodump(FILE *fp, long start, long count) +{ + int c, pos1, pos2; + long x = 0L; + char prtln[100]; + + while (((c = fgetc(fp)) != EOF) && (x != count)) + { + if (x%16 == 0) + { + memset(prtln,' ',sizeof prtln); + sprintf(prtln,"%0.6X ", start + x); + pos1 = 8; + pos2 = 45; + } + sprintf(prtln + pos1, "%0.2X", c); + if (isprint(c)) + sprintf(prtln + pos2, "%c", c); + else sprintf(prtln + pos2, "."); + pos1 += 2; + *(prtln+pos1) = ' '; + pos2++; + if (x % 4 == 3) + *(prtln + pos1++) = ' '; + if (x % 16 == 15) + printf("%s\n", prtln); + x++; + } + if (x % 16 != 15) + printf("%s\n", prtln); + return; +} + +static void skipb(FILE *fp, long start) +{ + long x = 0; + + if (start == 0) + return; + while (x < start) + { + fgetc(fp); + x++; + } + return; +} diff --git a/reference/C/CONTRIB/SNIP/hexorint.c b/reference/C/CONTRIB/SNIP/hexorint.c new file mode 100755 index 0000000..0ab0e31 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/hexorint.c @@ -0,0 +1,54 @@ +/* +** HEXORINT.C - Detect if a string denotes a hex or decimal +** number by detecting a leading "0X" or trailing "H" string. +** +** public domain demo by Bob Stout +*/ + +#include +#include + +#undef NUL +#define NUL '\0' + +#define LAST_CHAR(s) (((char *)s)[strlen(s) - 1]) + +/* +** Let strtol() do most of the work +*/ + +long hexorint(const char *string) +{ + int radix = 0; + char *dummy, valstr[128]; + + strcpy(valstr, string); + if (strchr("Hh", LAST_CHAR(valstr))) + { + LAST_CHAR(valstr) = NUL; + radix = 16; + } + return strtol(valstr, &dummy, radix); +} + +/* +** Test code follows - compile with TEST macro defined to test +*/ + +#ifdef TEST + +#include + +main(int argc, char *argv[]) +{ + long val; + + while (--argc) + { + val = hexorint(*(++argv)); + printf("Value of %s = %ld = %#lx\n", *argv, val, val); + } + return EXIT_SUCCESS; +} + +#endif /* TEST */ diff --git a/reference/C/CONTRIB/SNIP/hilobyte.h b/reference/C/CONTRIB/SNIP/hilobyte.h new file mode 100755 index 0000000..020bf04 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/hilobyte.h @@ -0,0 +1,2 @@ +#define LOBYTE(x) ((unsigned char)(x)) +#define HIBYTE(x) ((unsigned int)(x) >> 8) diff --git a/reference/C/CONTRIB/SNIP/hires.asm b/reference/C/CONTRIB/SNIP/hires.asm new file mode 100755 index 0000000..1c83f68 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/hires.asm @@ -0,0 +1,37 @@ +1. 80 x 50 on VGA +================= + mov ax,1202h ; select 400 scan line mode + mov bl,30h + int 10h + mov ax,3 ; select 80 x 25 16 colour mode + int 10h + mov ax,1112h ; load 8x8 character set into RAM + mov bl,0 + int 10h + +2. 80 x 43 on EGA +================= + mov ax,3 ; establish 350 scan line mode + int 10h ; and 80 x 25 16 colour mode + mov ax,1112h ; 8x8 character set + mov bl,0 + int 10h + mov ax,40h ; update cursor size/ pointers + mov es,ax + mov dx,es:[63h] + mov ax,060ah + out dx,ax + mov ax,000bh + out dx,ax + mov ax,12h ; set up new prtscr routine + mov bl,20h + int 10h + +Warnings: +========= +DOS's ANSI.SYS prior to DOS 5 has no comprehension of screens having more +than 25 lines! + +Reference: +"Programmer's Guide to PC and PS/2 Video Systems": author Richard Wilton. +Microsoft Press 1988. ISBN 1-55615-103-9 diff --git a/reference/C/CONTRIB/SNIP/howdy.c b/reference/C/CONTRIB/SNIP/howdy.c new file mode 100755 index 0000000..9c5212e --- /dev/null +++ b/reference/C/CONTRIB/SNIP/howdy.c @@ -0,0 +1,21 @@ +#define _ putchar +#define __ ^ +#define ___ / +#include +void main() +{_((2*2*2*2*2*2*3*41)___ +64__(3*17));_((2*2*2*13*89)___ +104__(2*2*3*5));_((2*2*2*23*61)___ +92__(2*11));_((2*2*2*2*2*3*3)___ +4__(2*2*3*3));_((2*2*2*2*7*13)___ +26__(3*29));_((2*2*3*7*19)___ +28__(3*7));_((2*2*2*2*13*29)___ +104__(2*13));_((2*2*2*2*2*2*3*19)___ +114__(3*29));_((2*2*5*107)___ +20__(2*2));_((3*11*97)___ +97__(83));_((2*2*2*2*2*3*11)___ +11__(2*2*3));_((2*5*11*13)___ +55__(2*3*3*7));_((2*3*7*83)___ +83__(2*2));_((79)___ +79__(11)); +} diff --git a/reference/C/CONTRIB/SNIP/hstr_i.c b/reference/C/CONTRIB/SNIP/hstr_i.c new file mode 100755 index 0000000..a0976b9 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/hstr_i.c @@ -0,0 +1,48 @@ +/* +** Originally published as part of the MicroFirm Function Library +** +** Copyright 1986, S.E. Margison +** Copyright 1989, Robert B.Stout +** +** Subset version released to the public domain, 1992 +** +** Make an ascii hexadecimal string into an integer. +*/ + +#include +#include + +unsigned int hstr_i(char *cptr) +{ + unsigned int i, j = 0; + + while (cptr && *cptr && isxdigit(*cptr)) + { + i = *cptr++ - '0'; + if (9 < i) + i -= 7; + j <<= 4; + j |= (i & 0x0f); + } + return(j); +} + +#ifdef TEST + +#include +#include + +int main(int argc, char *argv[]) +{ + char *arg; + unsigned int x; + + while (--argc) + { + x = hstr_i(arg = *++argv); + printf("Hex %s = %d\n", arg, x, x); + } + return EXIT_SUCCESS; +} + +#endif /* TEST */ diff --git a/reference/C/CONTRIB/SNIP/hugeread.c b/reference/C/CONTRIB/SNIP/hugeread.c new file mode 100755 index 0000000..fa981c6 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/hugeread.c @@ -0,0 +1,242 @@ +/* +** HUGEREAD.C - "Universal" PC read and write functions using huge data +** and far pointers. +** +** NOTES: +** +** 1. If these functions are called with a prototype in scope, passed +** parameters will be coerced to the proper data types. +** +** 2. Since these call read() and write(), all normal mode flags which +** are supported by individual compilers will be honored. +** +** 3. In small data memory models (S, T, and M), an intermediate buffer +** is allocated and used. In large data models (L and C), the data +** are read/written directly from/to target memory. +** +** 4. Like many mixed-model functions, this may generate lots of warnings +** with many compilers. Despite this, it really does generate correct +** code for all major PC compilers. +** +** Original Copyright 1992 by Bob Stout as part of +** the MicroFirm Function Library (MFL) +** +** This subset version is hereby donated to the public domain. +*/ + +#include +#include +#include +#include +#include + +#ifdef __TURBOC__ + #define FAR far +#else + #define FAR _far +#endif + +#ifndef min + #define min(x,y) (((x) <= (y)) ? (x) : (y)) +#endif + +#ifndef MK_FP + #define MK_FP(seg,offset) \ + ((void FAR *)(((unsigned long)(seg)<<16) | (unsigned)(offset))) +#endif + +/* +** Get the largest buffer possible. +*/ + +static size_t gettmp(char **buf) +{ + size_t bufsiz; + + for (bufsiz = 0x4000; bufsiz >= 128; bufsiz >>= 1) + { + if (NULL != (*buf = (char *) malloc(bufsiz))) + return bufsiz; + } + return 0; +} + +/* +** Normalize a far pointer +*/ + +void FAR *farnormal(void FAR *ptr) +{ + unsigned long base, para; + + base = (unsigned long)(ptr & 0xffff000fL); + para = (unsigned long)(ptr & 0x0000fff0L); + para <<= 12; + return (void FAR *)(base + para); +} + +/* +** Read any size block to anywhere in memory +*/ + +long hugeread(int fh, char FAR *buf, long size) +{ + long count; + size_t bufsiz; + char *tmp; + long ercode = size; + + if (4 > sizeof(void *)) + { + if (0 == (bufsiz = gettmp(&tmp))) + return -1L; + } + else + { + tmp = (char *)buf; + bufsiz = 0x4000; + } + + while (0 < (count = min(size, (long)bufsiz))) + { + int i, numread = read(fh, tmp, (size_t)count); + + if (1 > numread || numread != (int)count) + return -1L; + if (4 > sizeof(void *)) + { + for (i = 0; i < count; ++i) + buf[i] = tmp[i]; + } + buf = farnormal(buf + count); + size -= count; + if (2 < sizeof(void *)) + tmp = (char *)buf; + } + return ercode; +} + +/* +** Write any size block from anywhere in memory +*/ + +long hugewrite(int fh, char FAR *buf, long size) +{ + long count; + size_t bufsiz; + char *tmp; + long ercode = size; + + if (4 > sizeof(void *)) + { + if (0 == (bufsiz = gettmp(&tmp))) + return -1L; + } + else + { + tmp = (char *)buf; + bufsiz = 0x4000; + } + + while (0 < (count = min(size, (long)bufsiz))) + { + int i, numwrite; + + if (4 > sizeof(void *)) + { + for (i = 0; i < count; ++i) + tmp[i] = buf[i]; + } + numwrite = write(fh, tmp, (size_t)count); + if (1 > numwrite || numwrite != (int)count) + return -1L; + buf = farnormal(buf + count); + size -= count; + if (2 < sizeof(void *)) + tmp = (char *)buf; + } + return ercode; +} + +/* +** Read any size block to anywhere in memory +*/ + +long hugefread(FILE *fp, char FAR *buf, long size) +{ + long count; + size_t bufsiz; + char *tmp; + long ercode = size; + + if (4 > sizeof(void *)) + { + if (0 == (bufsiz = gettmp(&tmp))) + return -1L; + } + else + { + tmp = (char *)buf; + bufsiz = 0x4000; + } + + while (0 < (count = min(size, (long)bufsiz))) + { + int i, numread = fread(tmp, 1, (size_t)count, fp); + + if (1 > numread || numread != (int)count) + return -1L; + if (4 > sizeof(void *)) + { + for (i = 0; i < count; ++i) + buf[i] = tmp[i]; + } + buf = farnormal(buf + count); + size -= count; + if (2 < sizeof(void *)) + tmp = (char *)buf; + } + return ercode; +} + +/* +** Write any size block from anywhere in memory +*/ + +long hugefwrite(FILE *fp, char FAR *buf, long size) +{ + long count; + size_t bufsiz; + char *tmp; + long ercode = size; + + if (4 > sizeof(void *)) + { + if (0 == (bufsiz = gettmp(&tmp))) + return -1L; + } + else + { + tmp = (char *)buf; + bufsiz = 0x4000; + } + + while (0 < (count = min(size, (long)bufsiz))) + { + int i, numwrite; + + if (4 > sizeof(void *)) + { + for (i = 0; i < count; ++i) + tmp[i] = buf[i]; + } + numwrite = fwrite(tmp, 1, (size_t)count, fp); + if (1 > numwrite || numwrite != (int)count) + return -1L; + buf = farnormal(buf + count); + size -= count; + if (2 < sizeof(void *)) + tmp = (char *)buf; + } + return ercode; +} diff --git a/reference/C/CONTRIB/SNIP/hugesort.c b/reference/C/CONTRIB/SNIP/hugesort.c new file mode 100755 index 0000000..152aef9 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/hugesort.c @@ -0,0 +1,105 @@ +/* +** hugesort.c -- huge qsort() -- public domain by Raymond Gardner 6/92 +** tested with Borland C++ 3.0 (C mode) +*/ + +static void swap(char huge *a, char huge *b, unsigned n) +{ + char tmp; + + do + { + tmp = *a; *a++ = *b; *b++ = tmp; + } while ( --n ); +} +void hugesort(void huge *basep, + unsigned nel, + unsigned width, + int (*comp)(void huge *, void huge *)) +{ + char huge *i, huge *j; + unsigned int lnel, rnel; + char huge *base = (char huge *)basep; + + while (nel > 1) + { + swap(base, base + (long)width * (nel / 2), width); + for (i = base, j = base + (long)width * nel; ; ) + { + do + j -= width; + while ( (*comp)(j, base) > 0 ); + do + i += width; + while ( i < j && (*comp)(i, base) < 0 ); + if (i >= j) + break; + swap(i, j, width); + } + swap(j, base, width); + lnel = (unsigned)((long)(j - base) / width); + rnel = nel - lnel - 1; + j += width; + if (lnel < rnel) + { + hugesort(base, lnel, width, comp); + base = j; + nel = rnel; + } + else + { + hugesort(j, rnel, width, comp); + nel = lnel; + } + } +} + +#ifdef TEST + +#include +#include +#include +#include + +#define PADSIZE 300 + +typedef struct x { + int key; + char pad[PADSIZE]; + } X; + +int cmpv(void huge *a, void huge *b) /* (note void huge *) passed here */ +{ + return ((X huge *)a)->key < ((X huge *)b)->key ? -1 : + ((X huge *)a)->key > ((X huge *)b)->key ? 1 : 0; +} + +int main(int argc, char **argv) +{ + X huge *v; + int n; + int i, j; + + n = 300; /* default element count */ + if (argc > 1) + n = atoi(argv[1]); + printf("test with %d elements\n", n); + v = farmalloc(sizeof(X) * (long)n); + assert(v); /* be sure we got memory */ + for (i = 0; i < n; ++i) /* random init */ + { + v[i].key = rand(); + for (j = 0; j < PADSIZE; ++j) + v[i].pad[j] = rand(); + } + for (i = 0; i < n; ++i) /* display before */ + printf(" %d", v[i].key); + printf("\n"); + hugesort(v, n, sizeof(X), cmpv); /* sort it */ + for ( i = 0; i < n; ++i ) /* display after */ + printf(" %d", v[i].key); + printf("\n"); + return 0; +} + +#endif diff --git a/reference/C/CONTRIB/SNIP/ifactor.c b/reference/C/CONTRIB/SNIP/ifactor.c new file mode 100755 index 0000000..900c57a --- /dev/null +++ b/reference/C/CONTRIB/SNIP/ifactor.c @@ -0,0 +1,66 @@ +/* +** ifactor.c -- print prime factorization of a number +** +** Ray Gardner -- 1985 -- public domain +*/ + +#include +#include + +int prevfact = 0; +void factor (long); +void show (long, int); + +void main (int argc, char *argv[]) +{ + while ( --argc ) + factor(atol(*++argv)); +} + +void factor (long n) +{ + long d; + int k; + long n0 = n; + prevfact = 0; + + printf("%ld ",n); + if ( n < 2 ) + { + printf("is less than 2.\n"); + return; + } + else if ( n > 2 ) + { + d = 2; + for ( k = 0; n % d == 0; k++ ) + n /= d; + if ( k ) + show(d,k); + for ( d = 3; d * d <= n; d += 2 ) + { + for ( k = 0; n % d == 0; k++ ) + n /= d; + if ( k ) + show(d,k); + } + } + if ( n > 1 ) + { + if ( n == n0 ) + printf(" is prime"); + else show(n,1); + } + printf("\n"); +} + +void show (long d, int k) +{ + if ( prevfact ) + printf(" * "); + else printf(" = "); + prevfact++; + printf("%ld",d); + if ( k > 1 ) + printf("^%d",k); +} diff --git a/reference/C/CONTRIB/SNIP/inchcvrt.c b/reference/C/CONTRIB/SNIP/inchcvrt.c new file mode 100755 index 0000000..fb2cdb6 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/inchcvrt.c @@ -0,0 +1,79 @@ +/* +** Convert English measurement units +** +** Takes command line arguments in inches and converts to: +** +** 1. feet and inches (expressed as floating point) +** 2. feet and inches (expressed as fraction) +** +** public domain demo by Bob Stout +** uses ROUND.H from SNIPPETS +*/ + +#include +#include +#include +#include "round.h" + +#define BASE 64.0 + +void cnvrt_inches(double input, + double *feet, + double *inches, + double *dec_inches, + double *num_inches, + double *den_inches) +{ + double quot, rem, temp; + + /* + ** Split feet and inches + */ + + *feet = floor(input / 12.0); + *inches = fmod(input, 12.0); + + /* + ** Get integer inches and fractions + */ + + *num_inches = modf(*inches, dec_inches) * BASE; + + *num_inches = fround(*num_inches, 0); + if (0.0 == *num_inches) + return; + + /* + ** Reduce fractions to lowest common denominator + */ + + for (*den_inches = BASE; + 0.0 == fmod(*num_inches, 2.0); + *den_inches /= 2.0, *num_inches /= 2.0) + { + ; + } +} + +main(int argc, char *argv[]) +{ + double arg, feet, inches, dec, num, den, dummy; + + while (--argc) + { + arg = atof(*(++argv)); + cnvrt_inches(arg, &feet, &inches, &dec, &num, &den); + printf("%f Inches = %d' %.5f\" or %d' %d", + arg, (int)feet, inches, (int)feet, (int)dec); + if (0.0 == num) + puts("\""); + else + { + printf("-%d/%d\"", (int)num, (int)den); + if (modf(num, &dummy)) + puts(" (approx.)"); + else puts(""); + } + } + return EXIT_SUCCESS; +} diff --git a/reference/C/CONTRIB/SNIP/initvars.c b/reference/C/CONTRIB/SNIP/initvars.c new file mode 100755 index 0000000..1fb2a6d --- /dev/null +++ b/reference/C/CONTRIB/SNIP/initvars.c @@ -0,0 +1,139 @@ +#include +#include +#include +#include +#include +#include + +/**** init_globals(fp, names, types, ...) +** +** public domain by Raymond Gardner Sept. 1991 +** +** fp is a FILE * to the (already fopen'ed) file containing +** initialization data +** names is a space-separated list of names of globals (as they +** are to appear in the data file) +** types is a list of datatype characters, corresponding to names +** i for a pointer to integer +** s for a pointer to string (already allocated char array) +** p for a pointer to pointer to char (space will be malloc'd) +** (NOTE: no whitespace allowed in types !!) +** followed by var arg list of pointers to variables to init +*/ + +#define LNSZ 256 + +int init_globals(FILE *fp, char *names, char *types, ...) +{ + char ln[LNSZ]; + char *p; + va_list arglist; + char *namep, *typep, name[40], *e; + void *argp; + int k; + + while ( fgets(ln, LNSZ, fp) ) { /* read init file */ + while ( isspace(ln[0]) ) /* drop leading whitespace */ + memmove(ln, ln+1, strlen(ln)); + if ( ln[0] == 0 ) /* skip if blank line */ + continue; + p = strchr(ln, '='); /* find equal sign */ + if ( p == NULL ) /* error if none */ + return -1; /* or continue; */ + while ( p > ln && isspace(p[-1]) ) { /* remove whitespace */ + memmove(p-1, p, strlen(p-1)); /* before = sign */ + --p; + } + *p++ = 0; /* plug EOS over = sign */ + while ( isspace(p[0]) ) /* remove leading space on */ + memmove(p, p+1, strlen(p)); /* init string */ + k = strlen(p) - 1; /* init string length */ + if ( k < 1 ) + return -1; + + if ( p[k] != '\n' ) /* if '\n' is missing, input */ + return -1; /* exceeded buffer; error return */ + p[k] = 0; /* plug EOS over newline */ + + va_start(arglist, types); /* setup for arglist search */ + + namep = names; /* init ptr to var names */ + typep = types; /* init ptr to var types */ + while ( *namep == ' ' ) /* skip blanks before namelist */ + ++namep; + while ( *typep ) { /* while any typelist items left...*/ + + argp = (void *)va_arg(arglist, void *); /* get var arg */ + + k = strcspn(namep, " "); /* length of namelist entry */ + memmove(name, namep, k); /* put into name hold area */ + name[k] = 0; /* terminate it */ + if ( strcmp(name, ln) != 0 ) { /* if it doesn't match... */ + namep += k; /* get next name */ + while ( *namep == ' ' ) + ++namep; + ++typep; /* get next type */ + } else { /* else name is found... */ + if ( *typep == 'i' ) { /* if it's an int, init it */ + *(int *)argp = atoi(p); + } else if ( *typep == 's' || *typep == 'p' ) { + if ( *p == '"' ) { /* is string in quotes? */ + ++p; /* skip leading quote, and */ + e = strchr(p, '"'); /* look for trailing quote */ + if ( e ) /* terminate string if found */ + *e = 0; + } + if ( *typep == 'p' ) { /* if it's a char *ptr */ + e = malloc(strlen(p) + 1); /* get space */ + if ( e == 0 ) { /* error if no space */ + return -1; /* call va_end(arglist); first? */ + } + *(char **)argp = e; + strcpy(*(char **)argp, p); /* copy in string */ + } else /* must be char array */ + strcpy(argp, p); /* copy in string */ + } else { + return -1; /* bad type */ + } + break; /* break search; get next line */ + } + } + va_end(arglist); + } + return 0; +} +#ifdef TEST + +int foo; +char bar[80]; +int baz; +char *quux; + +int main(int argc, char **argv) +{ + FILE *fp; + int k; + + if ( argc < 2 ) { + fprintf(stderr, "missing arg\n"); + exit(1); + } + + fp = fopen(argv[1], "r"); + assert(fp); + k = init_globals(fp, "foo bar baz quux", "isip", + &foo, bar, &baz, &quux); + printf("k: %d\n", k); + printf("foo: %d\nbar: <%s>\nbaz: %d\nquux: <%s>\n", + foo, bar, baz, quux); + fclose(fp); + + return 0; +} +#endif +/* test data file: +foo=123 +bar = "a test" + baz = 456 +quux= what is this +*/ diff --git a/reference/C/CONTRIB/SNIP/int2e.asm b/reference/C/CONTRIB/SNIP/int2e.asm new file mode 100755 index 0000000..e8c370e --- /dev/null +++ b/reference/C/CONTRIB/SNIP/int2e.asm @@ -0,0 +1,55 @@ + PAGE 55,132 + .LIST +; +; Interrupt 2Eh Call +; +; From information originally published in +; PC magazine, April 28, 1987. Requires +; MASM 5.1 or later. +; +; Adapted by Bob Stout. +; +; NOTES: INT 2Eh passes a formatted command line +; directly to the resident portion of +; COMMAND.COM for execution. It functions +; similarly to the 'EXEC' function in DOS +; but is generally quicker. This is an +; undocumented DOS function and is subject +; to change in future releases of DOS. It +; also aborts any .BAT file which invokes +; a program which uses it. Use with care! +; +; Assemble with: MASM /Mx /z ... +; TASM /jMASM /mx /z ... +; + +% .MODEL memodel,C ;Add model support via + ;command line macros, e.g. + ;MASM /Mx /Dmemodel=LARGE + + .CODE + + PUBLIC _Int_2E + +_Int_2E PROC USES SI DI DS ES, command:PTR + Mov CS:SaveSP,SP + Mov CS:SaveSS,SS + IF @DataSize + Lds SI,command + ELSE + Mov SI,command + Endif + + Int 2Eh + + Mov AX,CS:SaveSS + Mov SS,AX + Mov SP,CS:SaveSP + Ret + +SaveSS Dw ? +SaveSP Dw ? + +_Int_2E ENDP + + End diff --git a/reference/C/CONTRIB/SNIP/iostutor.txt b/reference/C/CONTRIB/SNIP/iostutor.txt new file mode 100755 index 0000000..98ca27e --- /dev/null +++ b/reference/C/CONTRIB/SNIP/iostutor.txt @@ -0,0 +1,260 @@ +PROLOGUE -------- + +This tutorial started out as a "small" example of how to interface an I/O +object into the AT&T iostream classes currently provided with almost every +C++ compiler. When I say "small", I mean just that - but the scope of the +information I wanted to present really didn't fit well into that little hole, +so it turned out a little larger than I had initially hoped. However, I think +the effort was worth it - I know it was for me, since although I've done code +which deals with ostream, I hadn't fooled at all with istream derived +facilities, and learned some new things in the process. + +I can't really cite any single reference on iostreams that might prove useful +for those wanting to go further other than the AT&T iostreams reference +manual (my copy is out on loan at the moment so I can't quote the ISBN +number). I have never come across one which is more complete than this +reference, and most other references (including documentation from MSC/C++C, +Borland, IBM etc.) tend to quote from it fairly liberally, but lack any of +the important information needed to put it all together. While Microsoft's +C++ tutorial reference has some great hints for getting started in iostream +manipulators, it lacks in providing any information on interfacing to the +iostream classes themselves. + +Hopefully the information I've provided below will make some sense. It is as +complete as I could make it without really going overboard. Most of the +ostream related code is gleaned from my own library, but the rest is brand +new. + +The text of this tutorial and the accompanying source code are donated to the +public domain. + + +Tutorial in iostreams --------------------- + +This little project started out with the following aims: + +A) To define a simple input/output object, one that consumes bytes sent to + it and generates data for input into a sample program. It should there- + fore feature a "read" and "write" function. The object created is simply + a loopback buffer - input is queued immediately for output in FIFO (first + in first out) fashion. + +B) To create a streams interface for this object, so that existing facili- + ties for I/O in the AT&T streams classes can be used directly in a + polymorphic fashion (ie. make use of C++ inheritance & virtual dispatch). + + Specifically, I wanted to demonstrate the following aspects of iostreams: + + - Use of buffered vs. unbuffered I/O + + - Using the streams buffer for both input and output operations. (an + interface to iostream, rather than just istream or ostream) + + - How the put, get and putback buffers work + +C) To write a trivial application which uses both components and provide a + means of interactively demonstrating how it all works. + + +A - The I/O Object ---------------- + +class Myio; + +This class is simply a front-end for a circular buffer. Input bytes are added +at the head, and read from the tail. It is fixed in size, set by the +constructor. + +Two read/write functions are provided to access any contained data: + + int Myio::read (char * buf, int max); + int Myio::write (char const * buf, int len); + +These are both non-blocking calls which return the number of bytes read or +written. They know nothing about line delineation - only about raw bytes, as +would be the case for almost any I/O device. + +In addition, an internal flag is maintained to indicate when a write results +in a buffer 'overflow' (an attempt to write more bytes than will fit in the +buffer) and 'underflow' (an attempt to read an empty buffer). These flags +reflect the last write and read calls respectively, and are reset or set on +each write or read call. The members Myio::readok() and Myio::writeok() +rturn the settings as a boolean value. + +A Myio object can also optionally create a stream. It is created and comes +into life when the member function Myio::stream() is called. If it was +previously created, this function simply returns a reference to the existing +stream. The stream, if it exists, is deleted by the destructor. + +Myio's stream is an iostream, which inherits all of the abilities of both +ostream (for output) and istream (for input), including all operators. This, +of course, is the primary benefit of using streams! + + +B - The Streams Interface ----------------------- + +class Mystreambuf; class Mystreambase; class Mystream; + +Three classes as above are used. Mystreambuf derives from streambuf, and is +responsible for the input output operations and buffering on behalf of a Myio +object. Mystreambase is used as a base class for Mystream to assist in the +initialisation of the (My)streambuf passed to the iostream constructor. + +The iostream side is in fact very simple. Nothing really needs to be +overridden, and all of the work is done in Mystreambuf, where all the action +really takes place. + +The relationship between the ios/stream classes and the streambuf family is +one of delegation rather than inheritance. The user/application accesses +streambuf I/O via the stream object, not directly. A class diagram showing +the basic iostream classes and our classes would look like: + + + _ istream _ / \ ios -- ostream -- iostream \ \ \ Mystream \_____ +Mystreambase _/ | | (owns) | streambuf -- Mystreambuf + + +All relationships, except the one marked "(owns)", indicate inheritance. The +'owns' relationship is where the delegation occurs. ios is inherited +virtually, so that there is only one combined 'ios' object at the root of the +streams inheritence tree. + +Within Mystreambuf, we need to override the functions responsible for actual +input and output. But first, let's discuss how this streambuf works. + +Mystreambuf uses a single buffer, using the default buffer size allocated for +any streambuf (under most operating systems, this will be 1024 bytes). Since +we are dealing with both input and output operations, and these operations +are independent so far as the streambuf is concerned (as is the case with, +for example, serial I/O, but *not* the case with files), the buffer is split +into two; the first half is used for writing, the second for reading. + +The buffer used for writing is called the "put" buffer. Nothing mysterious +there - when full, streambuf::overflow() function is called, and via virtual +dispatch calls our Mystreambuf::overflow() which takes the contents of the +buffer and writes it to the output device. + +The read - or "get" - buffer is slightly more complex. There are occasions in +dealing with an input stream where it is convenient to know what's next +without actually removing it from the stream. That way, you can use the next +character as an indication of what to do next. For example, if you're parsing +a number, you want to know whether or not the next character is a valid +digit, and stop parsing if it isn't. The read side therefore incorporates the +idea of a "putback" buffer - after being read, the character can be placed +back into the input stream. + +The putback buffer is entirely the responsibility of any streambuf derived +class. It most you need to support a one character putback buffer - it is not +valid to remove, and then restore, more than one character from the stream. +It is also not valid put 'putback' any character but the one that was the +result of the last 'get'. It really must be "put back", not any old +character "pushed" (you could actually support 'pushing' data into the stream +if you wanted to, but you shouldn't use putback to do it). + +The get buffer is set up as: + + Offset 0 1 2 3 .... n | | | | to end of buffer | ++---+---+---+---------------------+ ^ ^ | +- Start of get buffer (where data +is read in) | +- Where data is putback + +Each time streambuf runs out of characters to give to its client, the +underflow() function is called. This fills the get buffer (get buffer size - +1, starting at offset 1) and reserves the first byte in case the previously +read character needs to be put back. + +streambuf provides internal pointers into the put, get and putback areas. All +of the I/O functions it provides handle these automatically. In our +underflow() and overflow() functions, we need to set these pointers according +to where and how much data is read in. + +I mentioned above that in our case, the input & output streams are +independant. That's not entirely the case - it may happen that when reading +from the Myio buffer we run out of data and need additional data in the +output stream buffer not yet written to Myio. We therefore flush the output +stream before retrieving any data by calling overflow() directly from within +underflow(). + +The sync() function is also overridden. This simply empties all buffers by +flushing the output buffer and discarding any buffered input. + + +C - The Application ----------------- + +The application itself is a simple menu, offering choice to send a line of +output to the IO object (via its stream), read one in, and dump/display +information both about the stream and Myio object. + +This added two other classes to the project: + + - myApplication: the actual application, implemented as a class. The + only way to go in C++. :-) + + - myList: a simple line input class, whose sole purpose in life is to + extract a linefeed delimited line from any istream object and return it + as a char const *. (I posted this code last week, but have since fixed + one minor bug I found in the process of developing Myio). + +A couple of subtle points - class myApplication uses a pointer to member +function it its menu selection. This is not the only way of doing this of +course, but I thought it was a good way of demonstrating a very C++ specific +concept, operator ->*, which does not exist at all in C. + +Additional notes are included in the source comments. + + +Making the application ---------------------- + +Hopefully this is a fairly simple thing to do - just compile the modules: + + Myiodemo.cpp Myio.cpp Mystream.cpp myLine.cpp + +and link them together. A simple makefile is provided - take a look at the +definitions at the top, adjust as desired, and type "make" (or nmake). If you +use any of Borland's compilers, just add the above files to a new project +called "Myiodemo.PRJ", set it to produce a .EXE (*not* Windows or PM based) +and press F9. + +Assuming a C++ compiler compatibile with cfront 2.1 and the presence of an +iostreans 1.2 library, the only non-portable part of this app is the use of +getch() from conio.h. This isn't easily provided under a UNIX system. You can +either fudge it by writing a getch() which switches into/out of 'raw' mode, +or use getchar() and clear everything up to and including a CR or NL after +the first character (the user still has to hit CR for input to get to the +program). + + + +EPILOGUE -------- + +Just some notes as to use of this code. If you need an output or input only +class, then you use ostream or istream wherever iostream is mentioned in this +example. Also, if you use buffered mode (you can support it or not - you can +even ignore the streambuf setting at your discretion), then you can use the +entire buffer rather than just half each for input output. + +If you interface to an input only object, you only need to override +streambuf::underflow(). Conversely, you override streambuf::overflow() for an +output only object. I have noticed that *some* implementations of iostreams +define the overflow() and underflow() methods as pure virtual functions, +whereas the AT&T default defines each as simply returning EOF. + +If portability is any concern, you may need to override the function you +aren't using in this fashion. The default sync() simply returns 0 (success), +but again, this is sometimes defined as a pure virtual, so you may need to +define it in your implementation. + +In some cases, you may wish to "switch" between unbuffered and buffered +modes. This is easily done by defining a function in Mystream which does it, +and this object is of course accessible in your I/O object (in this case +Myio). The only thing you need to remember is to flush all the buffers by +calling sync() when switching from buffered to unbuffered mode. + +Note also that some streambuf constructors take an existing buffer. This +means that you can use buffers already provided in your I/O object directly +rather than being forced to "double buffer" anything. Your buffer can also +be any size you like, subject to memory and other architecture constraints. + + +Enjoy! + +David Nugent - 3:632/348@fidonet.org +Moderor ('93-'94) of the FidoNet international C++ EchoMail conference diff --git a/reference/C/CONTRIB/SNIP/iscons.c b/reference/C/CONTRIB/SNIP/iscons.c new file mode 100755 index 0000000..b757d89 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/iscons.c @@ -0,0 +1,39 @@ +/* +** iscons() +** +** A function to determine if a specified stream refers to the console. +** +** Original Copyright 1988-1991 by Bob Stout as part of +** the MicroFirm Function Library (MFL) +** +** This subset version is hereby donated to the public domain. +*/ + +#include +#include + +#define BOOL(x) (!(!(x))) + +int iscons(FILE *fp) +{ + union REGS regs; + + regs.x.ax = 0x4400; + regs.x.bx = (unsigned)fileno(fp); + intdos(®s, ®s); + if (0 == (regs.x.ax & 0x80)) + return 0; + return BOOL(regs.x.ax & 0x13); +} + +#ifdef TEST + +int main(void) +{ + fprintf(stderr, "stdin is%s redirected\n", + iscons(stdin) ? " not" : ""); + fprintf(stderr, "stdout is%s redirected\n", + iscons(stdout) ? " not" : ""); +} + +#endif /* TEST */ diff --git a/reference/C/CONTRIB/SNIP/isfopen.c b/reference/C/CONTRIB/SNIP/isfopen.c new file mode 100755 index 0000000..4a88f1d --- /dev/null +++ b/reference/C/CONTRIB/SNIP/isfopen.c @@ -0,0 +1,41 @@ +/* +** Find out if a FILE * is valid +** +** public domain demo by Bob Stout +*/ + +#include + +#ifdef __TURBOC__ + #define STREAM_BUF _streams + #define FCNT FOPEN_MAX + #define FLAG flags +#else /* MSC, ZTC++ */ + #define STREAM_BUF _iob + #define FCNT _NFILE + #define FLAG _flag +#endif + +typedef enum {FALSE, TRUE} LOGICAL; + +int isfopen(FILE *fp) +{ + int i; + + for (i = 0; i < FCNT; ++i) + { + if (0 != STREAM_BUF[i].FLAG && fp == &STREAM_BUF[i]) + return TRUE; + } + return FALSE; +} + +#ifdef TEST + +void main(void) +{ + printf("stdout is%s valid\n", isfopen(stdout) ? "":" not"); + printf("buffer #10 is%s valid\n", isfopen(&STREAM_BUF[9]) ? "":" not"); +} + +#endif /*TEST */ diff --git a/reference/C/CONTRIB/SNIP/isisbn.c b/reference/C/CONTRIB/SNIP/isisbn.c new file mode 100755 index 0000000..6fccee7 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/isisbn.c @@ -0,0 +1,25 @@ +/* +** ISISBN.C - Validate International Standard Book Numbers (ISBNs) +** +** public domain by Maynard Hogg +*/ + +#include + +int isbn2(char *str) +{ + int i = 0; + int test = 0; + int c; + + while ('\0' != (c = *str++)) + { + if (isdigit(c)) + c -= '0'; + else if (i == 9 && 'X' == c) + c = 10; + else continue; + test += c * ++i; + } + return (i == 10 && test % 11 == 0); +} diff --git a/reference/C/CONTRIB/SNIP/isnetdr.c b/reference/C/CONTRIB/SNIP/isnetdr.c new file mode 100755 index 0000000..0e90e57 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/isnetdr.c @@ -0,0 +1,45 @@ +/*----------------------------------------------------------------------*/ +/* determine_drive_type -- Public Domain code from Bob Dolan */ +/* */ +/* INPUT: the drive number ( 0=current, 1=A:, 2=B:, etc. ) */ +/* OUTPUT: drive type ( 0=physical drive, 1=Network drive, 2=RamDisk ) */ +/*----------------------------------------------------------------------*/ + +#include + +drive_type(int dr) +{ + union REGS regs; + + regs.x.ax = 0x4409; /* IOCTL func 9 */ + regs.h.bl = (unsigned char)dr; + int86(0x21, ®s, ®s); + if (!regs.x.cflag) + { + if (regs.x.dx & 0x1000) + return 1; /* Network drive */ + + else if (regs.x.dx == 0x0800) + return 2; /* RAMdisk */ + } + + return 0; /* physical drive */ +} + +#ifdef TEST + +#include +#include +#include + +int main(int argc, char *argv[]) +{ + int dr = 0; + + if (1 < argc) + dr = toupper(*argv[1]) - '@'; + printf ("drive_type(%d) = %d\n", dr, drive_type(dr)); + return 0; +} + +#endif /* TEST */ diff --git a/reference/C/CONTRIB/SNIP/ispow2.c b/reference/C/CONTRIB/SNIP/ispow2.c new file mode 100755 index 0000000..52f860d --- /dev/null +++ b/reference/C/CONTRIB/SNIP/ispow2.c @@ -0,0 +1,12 @@ +#include + +int another_function(int x) { return! ((~(~0U>>1)|x)&x -1) ;} + +int main(void) +{ + int i; + + for (i = 0; i < 256; ++i) + printf("%3d: %d\n", i, another_function(i)); + return 0; +} diff --git a/reference/C/CONTRIB/SNIP/isqrt.c b/reference/C/CONTRIB/SNIP/isqrt.c new file mode 100755 index 0000000..cbc5048 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/isqrt.c @@ -0,0 +1,91 @@ +#include + +#define BITSPERLONG 32 + +#define TOP2BITS(x) ((x & (3 << (BITSPERLONG-2))) >> (BITSPERLONG-2)) + + +/* usqrt: + ENTRY x: unsigned long + EXIT returns floor(sqrt(x) * pow(2, BITSPERLONG/2)) + + Since the square root never uses more than half the bits + of the input, we use the other half of the bits to contain + extra bits of precision after the binary point. + + EXAMPLE + suppose BITSPERLONG = 32 + then usqrt(144) = 786432 = 12 * 65536 + usqrt(32) = 370727 = 5.66 * 65536 + + NOTES + (1) change BITSPERLONG to BITSPERLONG/2 if you do not want + the answer scaled. Indeed, if you want n bits of + precision after the binary point, use BITSPERLONG/2+n. + The code assumes that BITSPERLONG is even. + (2) This is really better off being written in assembly. + The line marked below is really a "arithmetic shift left" + on the double-long value with r in the upper half + and x in the lower half. This operation is typically + expressible in only one or two assembly instructions. + (3) Unrolling this loop is probably not a bad idea. + + ALGORITHM + The calculations are the base-two analogue of the square + root algorithm we all learned in grammar school. Since we're + in base 2, there is only one nontrivial trial multiplier. + + Notice that absolutely no multiplications or divisions are performed. + This means it'll be fast on a wide range of processors. +*/ + +struct int_sqrt { + unsigned sqrt, + frac; +}; + +void usqrt(unsigned long x, struct int_sqrt *q) +{ + unsigned long a = 0L; /* accumulator */ + unsigned long r = 0L; /* remainder */ + unsigned long e = 0L; /* trial product */ + + int i; + + for (i = 0; i < BITSPERLONG; i++) /* NOTE 1 */ + { + r = (r << 2) + TOP2BITS(x); x <<= 2; /* NOTE 2 */ + a <<= 1; + e = (a << 1) + 1; + if (r >= e) + { + r -= e; + a++; + } + } + memcpy(q, &a, sizeof(long)); +} + +#ifdef TEST + +#include +#include + +main(void) +{ + int i; + unsigned long l = 0x3fed0169; + struct int_sqrt q; + + for (i = 0; i < 101; ++i) + { + usqrt(i, &q); + printf("sqrt(%3d) = %2d, remainder = %2d\n", + i, q.sqrt, q. frac); + } + usqrt(l, &q); + printf("\nsqrt(%lX) = %X, remainder = %X\n", l, q.sqrt, q.frac); + return 0; +} + +#endif /* TEST */ diff --git a/reference/C/CONTRIB/SNIP/isramdsk.c b/reference/C/CONTRIB/SNIP/isramdsk.c new file mode 100755 index 0000000..30eb8d7 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/isramdsk.c @@ -0,0 +1,56 @@ +/* +** isRamDsk() - Determine if a drive is a RAM disk +** +** Call with drive letter ('a' - 'z', 'A' - 'Z') +** +** Returns TRUE, FALSE, or ERROR +** +** Uses ABSDISKC.C, ABSDISK.ASM, and DOS5BOOT.H from SNIPPETS +** (Note: The relevent parts of the structure in DOS5BOOT.H are +** also applicable to lower version numbers of DOS) +** +** Public domain by Bob Stout +*/ + +#include +#include +#include +#include "dos5boot.h" + +int AbsDiskRead(unsigned short, size_t, size_t, void *); + +typedef enum {ERROR = -1, FALSE, TRUE} LOGICAL; + +LOGICAL isRamDsk(unsigned char drive) +{ + union REGS regs; + B_REC buffer; + + regs.x.ax = 0x4408; /* Not if removable */ + regs.h.bl = (unsigned)toupper(drive) - (unsigned char)'@'; + intdos(®s, ®s); + if (0 == regs.x.ax) + return FALSE; + if (AbsDiskRead(toupper(drive) - 'A', 1, 0, &buffer)) + return ERROR; + return (1 == buffer.bsFATs); +} + +#ifdef TEST + +#include +#include + +int main(int argc, char *argv[]) +{ + if (2 > argc) + { + puts("Syntax: ISRAMDSK drive_letter"); + return EXIT_FAILURE; + } + printf("Drive %c: is%s a RAM drive\n", toupper(*argv[1]), + isRamDsk(*argv[1]) ? "" : " not"); + return EXIT_SUCCESS; +} + +#endif /* TEST */ diff --git a/reference/C/CONTRIB/SNIP/isshare.c b/reference/C/CONTRIB/SNIP/isshare.c new file mode 100755 index 0000000..1a7bbd5 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/isshare.c @@ -0,0 +1,86 @@ +/* +** is_share() - This is a routine that allows a program to determine +** if file-sharing is enabled at run-time. +** +** What does this code do? First - it checks to make sure +** it is running under DOS 3.0+ - otherwise - no sharing. +** Next, it opens the program itself (the .EXE file) by using +** "argv[0]". This argument points to the actual program name +** complete with the path under DOS 3.0 or later. It then +** attempts to lock the first 500 bytes of the program on +** disk. If successful (i.e. return != -1), it unlocks the +** locked bytes and closes the file (actually the unlock is +** superfluous since closing the file releases all locks) and +** returns the a "TRUE" (1) result. If it fails, it closes +** the .EXE file and returns a "FALSE" (0) result. Note that +** this does not depend on opening a file in shared mode to +** test it. +** +** Example of usage: +** +** main(int argc, char *argv[]) +** { +** int sharing; +** +** sharing = is_share(argv[0]); +** . +** . +** if (sharing) +** { +** // open file in shared mode +** ... +** } +** else +** { +** // use "normal" open +** ... +** } +** } +** +** Revision History: +** +** 08/03/93 Original: "is_sharing()" by Mike Ratledge of fidonet +** 10/20/93 Revision: revised for library +** 04/03/94 Revision: "Portabalized" for SNIPPETS by Bob Stout +*/ + +#include +#include +#include + +#if defined(_MSC_VER) + #include + #include + + int lock(int fp, long ofs, long lng) + { + lseek(fp,0L,SEEK_SET); + return locking(fp,LK_LOCK,lng); + } + + int unlock(fp,ofs,lng) + { + lseek(fp,0L,SEEK_SET); + return locking(fp,LK_UNLCK,lng); + } +#endif + +int is_share(char *arg) +{ + FILE *exe; + + if (_osmajor < 3) + return(0); + + exe = fopen(arg, "rb"); + + if (0 == lock(fileno(exe), 0l, 500l)) + { + unlock(fileno(exe), 0l, 500l); + fclose(exe); + return(1); + } + + fclose(exe); + return(0); +} diff --git a/reference/C/CONTRIB/SNIP/isshift.c b/reference/C/CONTRIB/SNIP/isshift.c new file mode 100755 index 0000000..79c4cff --- /dev/null +++ b/reference/C/CONTRIB/SNIP/isshift.c @@ -0,0 +1,24 @@ +/*-------------------------[ IsShift ]--------------------------*/ +/* Determine whether a shift key is depressed */ +/* public domain snippet by Jeff Dunlop */ +/*--------------------------------------------------------------*/ +/* local: */ +/* key_flags = pointer to bios shift key area */ +/* return: */ +/* 1 if either shift key is depressed */ +/*--------------------------------------------------------------*/ + +#if !defined(MK_FP) + #define MK_FP(seg,off) ((void far *)(((long)(seg) << 16)|(unsigned)(off))) +#endif + +int IsShift(void) +{ + unsigned char far *keyflags = MK_FP(0x40, 0x17); + + return (*keyflags & 0x03); +} + +/* -or?- */ + +#define IsShift ((*MK_FP(0x40, 0x17)) & 0x03) diff --git a/reference/C/CONTRIB/SNIP/iswprot.c b/reference/C/CONTRIB/SNIP/iswprot.c new file mode 100755 index 0000000..3d2fb6b --- /dev/null +++ b/reference/C/CONTRIB/SNIP/iswprot.c @@ -0,0 +1,82 @@ +/* +** ISWPROT.C - Detect if floppy drive is write protected +** +** public domain by Bob Stout w/ corrections & additions by Wayne King +*/ + +#include + +#ifdef __TURBOC__ + #define FAR far +#else + #define FAR _far +#endif + +/* +** isWprot() +** +** Parameters: 1 - Drive number (A: = 0, B: = 1) +** +** Returns: -1 - Error +** 0 - Not write protected +** 1 write protected +** +** Note: If drive door is open, an error is returned but the critical +** error handler is NOT tripped +*/ + +int isWprot(int drive) +{ + union REGS regs; + struct SREGS sregs; + char buf[512], FAR *bufptr = (char FAR *)buf; /* Needed by MSC */ + + /* First read sector 0 */ + + segread(&sregs); + regs.x.ax = 0x201; + regs.x.cx = 1; + regs.x.dx = drive & 0x7f; + sregs.es = FP_SEG(bufptr); + regs.x.bx = FP_OFF(bufptr); + int86x(0x13, ®s, ®s, &sregs); + if (regs.x.cflag && regs.h.ah != 6) + { + regs.h.ah = 0x00; /* reset diskette subsystem */ + regs.h.dl = drive & 0x7f; + int86x(0x13, ®s, ®s, &sregs); + return -1; + } + + /* Try to write it back */ + + segread(&sregs); + regs.x.ax = 0x301; + regs.x.cx = 1; + regs.x.dx = drive & 0x7f; + sregs.es = FP_SEG(bufptr); + regs.x.bx = FP_OFF(bufptr); + int86x(0x13, ®s, ®s, &sregs); + return (3 == regs.h.ah); +} + +#ifdef TEST + +#include +#include + +int main(int argc, char *argv[]) +{ + int drive; + + if (2 > argc) + { + puts("Usage: ISWPROT drive_letter"); + return -1; + } + drive = toupper(argv[1][0]) - 'A'; + printf("isWprot(%c:) returned %d\n", drive + 'A', isWprot(drive)); + return 0; +} + +#endif diff --git a/reference/C/CONTRIB/SNIP/isxkbrd.c b/reference/C/CONTRIB/SNIP/isxkbrd.c new file mode 100755 index 0000000..b104a7c --- /dev/null +++ b/reference/C/CONTRIB/SNIP/isxkbrd.c @@ -0,0 +1,47 @@ +/* +** ISXKBRD.C - public domain by Ed Kowalski. +** +** isxkeybrd() - detects enhanced kbd +*/ + +#include + +/* +** Check for enhanced keyboard support. +*/ + +int isxkeybrd(void) +{ + union REGS rg; + unsigned kbdflags; + + rg.h.ah = 0x02; /* check BIOS supports enhanced kbd */ + int86(0x16, &rg, &rg); /* get kbd flags */ + kbdflags = rg.h.al; + + /* mess 'em up, get enhanced flags */ + + rg.x.ax = 0x1200 + kbdflags ^ 0xff; + int86(0x16, &rg, &rg); + if (rg.h.al == kbdflags) /* BIOS supports enhanced keyboard */ + { + /* if bit 4 at 40:96h is set machine has an enhanced kbd */ + + if ((*(( char far *) 0x400096L) & 0x10)) + return 1; /* enhanced keyboard present */ + } + return 0; /* don't use enhanced keyboard calls */ +} + +#ifdef TEST + +#include +main() +{ + if (isxkeybrd()) + puts( "Enhanced Keyboard supported" ); + else puts( "Enhanced Keyboard NOT supported "); + return 0; +} + +#endif /* TEST */ diff --git a/reference/C/CONTRIB/SNIP/jdn.c b/reference/C/CONTRIB/SNIP/jdn.c new file mode 100755 index 0000000..5f69923 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/jdn.c @@ -0,0 +1,124 @@ +/* jdn.c -- Julian Day Number computation +** +** public domain Julian Day Number functions +** +** Based on formulae originally posted by +** Tom Van Flandern / Washington, DC / metares@well.sf.ca.us +** in the UseNet newsgroup sci.astro. +** Reposted 14 May 1991 in FidoNet C Echo conference by +** Paul Schlyter (Stockholm) +** Minor corrections, added JDN to julian, and recast into C by +** Raymond Gardner Englewood, Colorado +** +** Synopsis: +** long ymd_to_jdn(int year, int month, int day, int julian_flag) +** void jdn_to_ymd(long jdn, int *year, int *month, int *day, +** int julian_flag) +** year is negative if BC +** if julian_flag is > 0, use Julian calendar +** if julian_flag is == 0, use Gregorian calendar +** if julian_flag is < 0, routines decide based on date +** +** These routines convert Gregorian and Julian calendar dates to and +** from Julian Day Numbers. Julian Day Numbers (JDN) are used by +** astronomers as a date/time measure independent of calendars and +** convenient for computing the elapsed time between dates. The JDN +** for any date/time is the number of days (including fractional +** days) elapsed since noon, 1 Jan 4713 BC. Julian Day Numbers were +** originated by Joseph Scaliger in 1582 and named after his father +** Julius, not after Julius Caesar. They are not related to the +** Julian calendar. +** +** For dates from 1 Jan 4713 BC thru 12 Dec Feb 32766 AD, ymd_to_jdn() +** will give the JDN for noon on that date. jdn_to_ymd() will compute +** the year, month, and day from the JDN. Years BC are given (and +** returned) as negative numbers. Note that there is no year 0 BC; +** the day before 1 Jan 1 AD is 31 Dec 1 BC. Note also that 1 BC, +** 5 BC, etc. are leap years. +** +** Pope Gregory XIII decreed that the Julian calendar would end on +** 4 Oct 1582 AD and that the next day would be 15 Oct 1582 in the +** Gregorian Calendar. The only other change is that centesimal +** years (years ending in 00) would no longer be leap years +** unless divisible by 400. Britain and its possessions and +** colonies continued to use the Julian calendar up until 2 Sep +** 1752, when the next day became 14 Sep 1752 in the Gregorian +** Calendar. These routines can be compiled to use either +** convention. By default, the British convention will be used. +** Simply #define PAPAL to use Pope Gregory's convention. +** +** Each routine takes, as its last argument, a flag to indicate +** whether to use the Julian or Gregorian calendar convention. If +** this flag is negative, the routines decide based on the date +** itself, using the changeover date described in the preceding +** paragraph. If the flag is zero, Gregorian conventions will be used, +** and if the flag is positive, Julian conventions will be used. +*/ + + +#ifdef PAPAL /* Pope Gregory XIII's decree */ +#define LASTJULDATE 15821004L /* last day to use Julian calendar */ +#define LASTJULJDN 2299160L /* jdn of same */ +#else /* British-American usage */ +#define LASTJULDATE 17520902L /* last day to use Julian calendar */ +#define LASTJULJDN 2361221L /* jdn of same */ +#endif + + +long ymd_to_jdn(int y, int m, int d, int julian) +{ + long jdn; + + if (julian < 0) /* set Julian flag if auto set */ + julian = (((y * 100L) + m) * 100 + d <= LASTJULDATE); + + if (y < 0) /* adjust BC year */ + y++; + + if (julian) + jdn = 367L * y - 7 * (y + 5001L + (m - 9) / 7) / 4 + + 275 * m / 9 + d + 1729777L; + else + jdn = (long)(d - 32076) + + 1461L * (y + 4800L + (m - 14) / 12) / 4 + + 367 * (m - 2 - (m - 14) / 12 * 12) / 12 + - 3 * ((y + 4900L + (m - 14) / 12) / 100) / 4 + + 1; /* correction by rdg */ + + return jdn; +} + + +void jdn_to_ymd(long jdn, int *yy, int *mm, int *dd, int julian) +{ + long x, z, m, d, y; + long daysPer400Years = 146097L; + long fudgedDaysPer4000Years = 1460970L + 31; + + if (julian < 0) /* set Julian flag if auto set */ + julian = (jdn <= LASTJULJDN); + + x = jdn + 68569L; + if ( julian ) + { + x += 38; + daysPer400Years = 146100L; + fudgedDaysPer4000Years = 1461000L + 1; + } + z = 4 * x / daysPer400Years; + x = x - (daysPer400Years * z + 3) / 4; + y = 4000 * (x + 1) / fudgedDaysPer4000Years; + x = x - 1461 * y / 4 + 31; + m = 80 * x / 2447; + d = x - 2447 * m / 80; + x = m / 11; + m = m + 2 - 12 * x; + y = 100 * (z - 49) + y + x; + + *yy = (int)y; + *mm = (int)m; + *dd = (int)d; + + if (*yy <= 0) /* adjust BC years */ + (*yy)--; +} diff --git a/reference/C/CONTRIB/SNIP/jgrep.c b/reference/C/CONTRIB/SNIP/jgrep.c new file mode 100755 index 0000000..9efcb29 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/jgrep.c @@ -0,0 +1,178 @@ +/* +** JGREP.C - A utility to search files for text. +** +** public domain by Jerry Coffin +** +** Link with wildargs.obj (Borland), setargv.obj (Microsoft), _mainX.obj +** (Symantech/Zortech), or wildargX.obj (Watcom) which allows you to pass +** wildcards on the command line. +*/ + +#include +#include +#include +#include +#include + +#define LINELEN 1024 +#define BUFSIZE 32767 + +#if defined(_QC) || defined(_MSC_VER) + void _cdecl _setenvp(void) {} + void _cdecl _nullcheck(void) {} +#endif + +enum { FALSE, TRUE }; + +typedef unsigned char uchar; + +static size_t table[UCHAR_MAX+1]; +static size_t len; +static char *string=NULL; + +void init_find(char *new_string) +{ + size_t i; + + if (NULL != string) + free(string); + string = strdup(new_string); + len = strlen(string); + + for (i=0;i<=UCHAR_MAX;i++) + table[i]=len; + for (i=0;i0) + pos+=shift; + if (0==shift) + { + if (!memcmp(string,here=string2+pos-len+1,len)) + return(here); + else pos++; + } + } + return NULL; +} + +char *find_no_case(char *string2) +{ + size_t limit = strlen(string2); + size_t shift; + size_t pos=len-1; + char *here; + + while (pos < limit) + { + while( pos < limit && + (shift=table[(uchar)toupper(string2[pos])])>0) + { + pos+=shift; + } + if (0==shift) + { + if (!memicmp(string,here=string2+pos-len+1,len)) + return(here); + else pos++; + } + } + return NULL; +} + +char *( *find) (char *)=find_case; + +int _cdecl main(int argc, char **argv) +{ + int k, first; + unsigned line; + int line_numbers=FALSE, reverse=FALSE, print_file_name=FALSE; + int no_case = TRUE; + char line_buffer[LINELEN],*string,c; + FILE *infile=NULL; + static char buffer[BUFSIZE]; + + while ((c=argv[1][0])=='/' || c=='-') + { + switch(tolower(argv[1][1])) + { + case 'c': + case 'y': + no_case=FALSE; + break; + + case 'f': + print_file_name=TRUE; + + case 'n': + line_numbers=TRUE; + break; + + case 'v': + reverse = TRUE; + break; + + default: + fprintf(stderr,"unknown switch -%c",argv[1][1]); + } + argv++; + argc--; + } + if (argc < 3) + { + fprintf(stderr ,"\nsyntax: find [-c|y][-n][-v][-f] " + "string filename ..." + "\n\t-c | -y : make case significant ('c' != 'C')" + "\n\t-n : number lines" + "\n\t-f : place file name before lines ( forces -n)" + "\n\t-v : print lines that don't match" + "\n - by itself to read from standard input"); + return(1); + } + + string=argv[1]; + if (no_case) + { + strupr(string); + find=find_no_case; + } + init_find(string); + for (k=2;k +#include "joystick.h" + +struct joystick JoyStick; + +/* +** read_joystick() +** +** returns SUCCESS or ERROR +** +** fills in global JoyStick structure +*/ + +LOGICAL read_joystick(void) +{ + union REGS regs; + + regs.h.ah = 0x84; /* Read the switches */ + regs.x.dx = 0; + int86(0x15, ®s, ®s); + if (regs.x.cflag) + return ERROR; + JoyStick.switch_0 = BOOL(regs.h.al & 0x10); + JoyStick.switch_1 = BOOL(regs.h.al & 0x20); + JoyStick.switch_2 = BOOL(regs.h.al & 0x40); + JoyStick.switch_3 = BOOL(regs.h.al & 0x80); + + regs.h.ah = 0x84; /* Read positions */ + regs.x.dx = 1; + int86(0x15, ®s, ®s); + if (regs.x.cflag) + return ERROR; + JoyStick.pos_Ax = regs.x.ax; + JoyStick.pos_Ay = regs.x.bx; + JoyStick.pos_Bx = regs.x.cx; + JoyStick.pos_By = regs.x.dx; + + return SUCCESS; +} diff --git a/reference/C/CONTRIB/SNIP/kb_data.c b/reference/C/CONTRIB/SNIP/kb_data.c new file mode 100755 index 0000000..e18093f --- /dev/null +++ b/reference/C/CONTRIB/SNIP/kb_data.c @@ -0,0 +1,50 @@ +/* by: Dan Kozak */ + +#include + +#ifdef __TURBOC__ + #define _far far +#endif + +typedef struct /* Keyboard status structure */ + { + unsigned int + right_shift_down : 1, /* Right Shift key depressed */ + left_shift_down : 1, /* Left Shift key depressed */ + ctrl_shift_down : 1, /* Ctrl key depressed */ + alt_shift_down : 1, /* Alt key depressed */ + scroll_on : 1, /* Scroll Lock is on */ + num_on : 1, /* Num Lock is on */ + caps_on : 1, /* Caps Lock is on */ + ins_on : 1, /* Insert state is active */ + filler : 3, /* Filler for word alignment */ + ctrl_numloc : 1, /* Suspend key is on */ + scroll_down : 1, /* Scroll Lock key depressed */ + num_down : 1, /* Num Lock key depressed */ + caps_down : 1, /* Caps Lock key depressed */ + ins_down : 1; /* Insert key depressed */ + } biosshiftstate; + +biosshiftstate _far *kbd_status = (biosshiftstate _far *) 0x00000417L; + +main() +{ + while(1) + { + printf("right_shift_down = %d\n",kbd_status->right_shift_down); + printf("left_shift_down = %d\n",kbd_status->left_shift_down); + printf("ctrl_shift_down = %d\n",kbd_status->ctrl_shift_down); + printf("alt_shift_down = %d\n",kbd_status->alt_shift_down); + printf("scroll_on = %d\n",kbd_status->scroll_on); + printf("num_on = %d\n",kbd_status->num_on); + printf("caps_on = %d\n",kbd_status->caps_on); + printf("ins_on = %d\n",kbd_status->ins_on); + printf("filler = %d\n",kbd_status->filler); + printf("ctrl_numloc = %d\n",kbd_status->ctrl_numloc); + printf("scroll_down = %d\n",kbd_status->scroll_down); + printf("num_down = %d\n",kbd_status->num_down); + printf("caps_down = %d\n",kbd_status->caps_down); + printf("ins_down = %d\n",kbd_status->ins_down); + } + return 0; +} diff --git a/reference/C/CONTRIB/SNIP/kbflip.c b/reference/C/CONTRIB/SNIP/kbflip.c new file mode 100755 index 0000000..a8fb934 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/kbflip.c @@ -0,0 +1,86 @@ +/* +** KBFLIP.C +** +** a public domain demo by: Bob Stout +*/ + +#include +#include +#include +#include + +#ifdef __TURBOC__ + #define FAR far +#else + #define FAR _far +#endif + +#define SHOW(str) fputs(str"\n", stderr) + +#define BitSet(arg,posn) ((arg) | (1L << (posn))) +#define BitClr(arg,posn) ((arg) & ~(1L << (posn))) + +#define LOCKS_POSN 4 +#define BYTE unsigned char + +BYTE FAR *kb_status = (BYTE FAR *) 0x00400017; + +/* +** Tell the folks how this works +*/ + +void usage(void) +{ + SHOW("Usage: KBFLIP {+|-}[switches] [...{+|-}[switches]]"); + SHOW("Where \"switches\" are one or more of:"); + SHOW(" +/-C - Turn Caps Lock on/off"); + SHOW(" +/-N - Turn Num Lock on/off"); + SHOW(" +/-S - Turn Scroll Lock on/off"); + SHOW("Note switches may be upper or lower case\n"); + SHOW("Example: \"KBFLIP +Cn -S\" turns Caps Lock and Num Lock on " + "and Scroll lock off"); + exit(-1); +} + +/* +** The real works starts here +** +** This works by checking the user input against a string containing the +** allowable switch characters in the same relative positions they +** occupy in the BIOS data area, offset by 4 (LOCKS_POSN). +** +** Note that all changes are made to a copy of the BIOS data so any +** input errors will not cause incomplete changes to be applied. +*/ + +int main(int argc, char *argv[]) +{ + int i, j; + char *args = "SNC"; + BYTE template = *kb_status; /* Make changes to copy */ + + if (2 > argc) /* Help 'em */ + usage(); + for (i = 1; i < argc; ++i) + { + if (NULL == strchr("+-", *argv[i])) + usage(); + + for (j = 1; argv[i][j]; ++j) + { + char *found; + + if (NULL != (found = strchr(args, toupper(argv[i][j])))) + { + int posn = LOCKS_POSN + (found - args); + + if ('+' == *argv[i]) + template = (BYTE)BitSet(template, posn); + else template = (BYTE)BitClr(template, posn); + } + else usage(); + } + } + *kb_status = template; /* Apply all changes */ + return(0); +} diff --git a/reference/C/CONTRIB/SNIP/keylocks.c b/reference/C/CONTRIB/SNIP/keylocks.c new file mode 100755 index 0000000..2c0880f --- /dev/null +++ b/reference/C/CONTRIB/SNIP/keylocks.c @@ -0,0 +1,21 @@ +static volatile unsigned char far *keyflags = (char far *)0x00400017; + +void setcaps(void) +{ + *keyflags |= 0x40; +} + +void clrcaps(void) +{ + *keyflags &= ~0x40; +} + +void setnumlock(void) +{ + *keyflags |= 0x20; +} + +void clrnumlock(void) +{ + *keyflags &= ~0x20; +} diff --git a/reference/C/CONTRIB/SNIP/keywatch.c b/reference/C/CONTRIB/SNIP/keywatch.c new file mode 100755 index 0000000..374f94b --- /dev/null +++ b/reference/C/CONTRIB/SNIP/keywatch.c @@ -0,0 +1,155 @@ +/* keywatch.c 12-29-91 Robert Mashlan, Public Domain *\ + + DOS compiler portability modifications added by Bob Stout, + 1:106/2000.6 + + This program monitors the keyboard interrupt, and stores the + status of each key as to whether it is pressed or released. + + This is done by capturing interrupt 9, and watching the make/break + codes. The status is updated in the keys array, where 1 means + that the key is pressed, while 0 means the key is released. The + key array is uses the scan code for an index instead of the ascii + character. It is simple enough to find the scan code for a key, + just run this program and watch the display. + + The ekeys array will reflect the status of keys found on an AT + keyboard. For instance, the left and right alt keys are + differentiated, as well as the edit control keys on the numeric + keypad and the one not on the numeric keypad. + + Since this program installs an interrupt handler, it should be + terminated normally, such the keyboard handler can be removed. + The ^C/^Break exit is captured via signal(), but all possible + exits should be trapped. + +\* */ + +#include +#include +#include +#include + +#define BYTE unsigned char +#if defined(__TURBOC__) + #define _interrupt interrupt + #define _far far + #define IN_PORT(port) inportb(port) + #define IN_PORTW(port) inport(port) + #define OUT_PORT(port, val) outportb(port, val) + #define OUT_PORTW(port, val) outport(port, val) +#else + #if defined(__ZTC__) + #include + #else /* MSC, QC, Watcom */ + #define getvect(n) _dos_getvect(n) + #define setvect(n,v) _dos_setvect(n,v) + #endif + #define IN_PORT(port) inp(port) + #define IN_PORTW(port) inpw(port) + #define OUT_PORT(port, val) outp(port, val) + #define OUT_PORTW(port, val) outpw(port, val) +#endif + +volatile char keys[128]; /* array of key states */ +volatile char ekeys[128]; /* array of AT key states */ + +#define KEYPORT 0x60 /* keyboard scan code port */ +#define keyport() IN_PORT(KEYPORT) + /* macro that returns the scancode of the key that caused */ + /* the interrupt */ + +/* Define: *\ + + installisr() + installation macro, installs newkbisr() in the keyboard + interrupt chain + + removeisr() + removal macro, call to remove newkbisr() from interrupt + chain. oldkbisr() must be removed before program ends +\* */ + +#ifdef __ZTC__ + #define installisr() int_intercept(0x09, newkbisr, 0) + #define removeisr() int_restore(0x09); +#else + #define installisr() (oldkbisr=getvect(0x09),setvect(0x09,newkbisr)) + #define removeisr() setvect(0x09,oldkbisr) + #ifdef __TURBOC__ + void _interrupt (_far *oldkbisr)(void); /* address of old ISR */ + #else + void (_interrupt _far *oldkbisr)(void); /* address of old ISR */ + #endif +#endif + +#ifdef __ZTC__ + int newkbisr(struct INT_DATA *pd) +#elif defined(__TURBOC__) + void _interrupt newkbisr(void) +#else + void _interrupt _far newkbisr(void) +#endif +{ + static extkey; + BYTE scancode = (BYTE)keyport(); /* read keyboard scan code */ + + if (scancode == 0xe0) + extkey = 1; /* use ekey array on next scan code */ + else + { + if (scancode & 0x80) /* key released */ + (extkey ? ekeys : keys)[scancode & 0x7f] = 0; + else (extkey ? ekeys : keys)[scancode] = 1; + extkey = 0; + } + +#ifdef __ZTC__ + return 0; /* chain to previous keyboard ISR */ +#else + oldkbisr(); /* chain to previous keyboard ISR */ +#endif +} + +int keyspressed(void) /* returns number of keys being held down */ +{ + int i, result = 0; + + for (i = 0; i < 128; i++) + { + result += keys[i]; + result += ekeys[i]; + } + return result; +} + +int main(void) +{ + int lastkeycount = 0; + + signal(SIGINT,SIG_IGN); /* ingnore ^C and ^Break */ + installisr(); /* install interrupt handler */ + while(1) + { + int i; + + if (keyspressed() != lastkeycount) /* change in keystatus */ + { + lastkeycount = keyspressed(); + puts("---"); + for(i = 0; i < 128; i++) + { + if (keys[i]) + printf("key with scan code %02x " + "has been pressed\n", i); + if (ekeys[i]) + printf("key with scan codes e0 %02x " + "had been pressed\n", i); + } + } + if (kbhit() && getch()==0x1b) /* terminate when Esc pressed */ + break; + } + removeisr(); /* remove interrupt handler */ + return 0; +} diff --git a/reference/C/CONTRIB/SNIP/killff.c b/reference/C/CONTRIB/SNIP/killff.c new file mode 100755 index 0000000..abfb1e0 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/killff.c @@ -0,0 +1,123 @@ +/* +** KILLFF.C - A program was written to strip out all the Form Feeds +** in text files. +** +** Public domain by Erik VanRiper, 12/22/91 +** Modified by Bob Stout, 17 Feb 93 +** +** Reads a text file and makes a duplicate with NO Form Feed +** characters! The default action is to create a duplicate without +** Form Feeds, then remove the original and rename the dupliicate, +** although an explicit output file name may be specified. +** +** Form Feed characters are replaced with newline characters ('\n'). +** Since ANSI mandates that fwrite() will translate newlines when +** a stream is opened in text (non-binary) mode, these will appear +** in the ouput file in a format appropriate to the implementation, +** e.g. CRLF pairs on PC's. +** +** Usage: KILLFF filename [newname] +*/ + +#include +#include +#include + +#define BSIZ 32768U /* max size of read/write buffer */ + +main(int argc, char *argv[]) +{ + FILE *in, *out; /* input and output files */ + char name[80], /* name of file to be fixed */ + temp[80], /* output file name */ + *buf; /* buffer we will use to write */ +/* *s; /* searching pointer */ + size_t bad, /* check to see if write ok */ + num; /* number of bytes read */ + int retval = EXIT_SUCCESS, /* return value */ + tmpflag = 0; /* non-zero if tmpnam() used */ + + printf("\nKILL FORM FEEDS by Erik VanRiper & Bob Stout\n\n"); + + if(argc < 2) /* usage info */ + { + puts("Usage: KILLFF input_file [output_file]"); + puts("\nIf no output file is given, the input file will " + "be replaced."); + return retval; /* return to OS */ + } + + strcpy(name,argv[1]); /* input filename */ + if(argc == 3) strcpy(temp,argv[2]); /* outfile name */ + else + { + tmpnam(temp); + tmpflag = -1; + } + + if((in = fopen(name,"r")) == NULL) /* Open in file */ + { + printf("\nCan't Open Input File %s",name); + return (retval = EXIT_FAILURE); /* return to OS */ + } + if((out = fopen(temp,"wt")) == NULL) /* open out file */ + { + printf("\nCan't Open Output File %s",temp); + fclose(in); /* close in file */ + return (retval = EXIT_FAILURE); /* return to OS */ + } + + if((buf = malloc(BSIZ)) == NULL) /* malloc a large buffer */ + { + printf("\nOut of memory\n"); + return (retval = EXIT_FAILURE); /* return to OS */ + } + + printf("Input file: %s Output file: %s\n", + name,tmpflag ? name : temp); + + /* read in file while chars to read */ + + while (0 < (num = fread(buf,sizeof(char),BSIZ,in))) + { + size_t i; + + for (i = 0; i < num; ++i) /* look for FF */ + if ('\f' == buf[i]) + buf[i] = '\n'; /* change to newline */ + + bad=fwrite(buf,sizeof(char),num,out); /* write out buf */ + if(bad != num) /* error */ + { + printf("\nCan't Write to %s ", temp); + retval = EXIT_FAILURE; /* return to OS */ + break; + } + } + fclose(in); /* close in file */ + fclose(out); /* close out file */ + free(buf); /* free memory */ + if (tmpflag) + { + if (remove(name)) + { + printf("Can't rename %s\n", name); + printf("Converted file is named %s\n", temp); + } + else + rename(temp, name); + } + printf("\nDone!"); /* Finished */ + return retval; /* return to OS */ +} +/* + +List this source file to test this program! + +New page + +New page + +All done + +*/ diff --git a/reference/C/CONTRIB/SNIP/lbitops.c b/reference/C/CONTRIB/SNIP/lbitops.c new file mode 100755 index 0000000..85040be --- /dev/null +++ b/reference/C/CONTRIB/SNIP/lbitops.c @@ -0,0 +1,46 @@ +/* +** large bit array operations by Scott Dudley +** with modifications by Auke Reitsma and Bob Stout +** +** Public domain +*/ + +#include + +/* +** The following macros assume CHAR_BIT is one of either 8, 16, or 32 +*/ + +#define MASK CHAR_BIT-1 +#define SHIFT ((CHAR_BIT==8)?3:(CHAR_BIT==16)?4:8) + +#define BitOff(a,x) ((void)((a)[(x)>>SHIFT] &= ~(1 << ((x)&MASK)))) +#define BitOn(a,x) ((void)((a)[(x)>>SHIFT] |= (1 << ((x)&MASK)))) +#define BitFlip(a,x) ((void)((a)[(x)>>SHIFT] ^= (1 << ((x)&MASK)))) +#define IsBit(a,x) ((a)[(x)>>SHIFT] & (1 << ((x)&MASK))) + +#include +#include + +int main(void) +{ + char array[64]; + + memset(array, '\0', sizeof(array)); + + BitOn(array, 5); + BitOn(array, 12); + BitOn(array, 500); + + if (IsBit(array, 5) && IsBit(array, 12) && IsBit(array, 500)) + puts("These functions seem to work!"); + else puts("Something's broken here!"); + + BitFlip(array, 12); + BitOff(array, 5); + + if (!IsBit(array, 5) && !IsBit(array, 12) && IsBit(array, 500)) + puts("These functions still seem to work!"); + else puts("Something's broken here!"); + return 0; +} diff --git a/reference/C/CONTRIB/SNIP/ldfloor.c b/reference/C/CONTRIB/SNIP/ldfloor.c new file mode 100755 index 0000000..acea285 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/ldfloor.c @@ -0,0 +1,41 @@ +/* ldfloor() -- long double floor +** public domain by Raymond Gardner Englewood, CO +** tested with TC++ +** assumptions: 80-bit IEEE format numbers, stored LSB first +** (Intel style), longs & ints are accessed from arbitrary boundaries +*/ + +long double ldfloor(long double a) +{ + long double a0; + int e, n; + + a0 = a; + e = ((int *)&a)[4] & 0x7FFF; /* extract exponent */ + if ( e == 0 ) /* 0 is special case */ + return (long double) 0.0; + e -= 16383; /* unbias exponent */ + if (e < 0) /* if < 0, num is < 1,... */ + { + a = 0.0; /* so floor is zero */ + } + else if ((n = 63 - e) > 0) /* clear n least sig. bits */ + { + if (n < 32) /* clear n lowest bits */ + { + ((unsigned long *)&a)[0] &= ~((1L << n) - 1); + } + else /* n >= 32 */ + { + ((unsigned long *)&a)[0] = 0; /* clear lower 32 bits */ + n -= 32; /* how many left to clear ? */ + if (n) /* if any, clear n next lowest bits */ + { + ((unsigned long *)&a)[1] &= ~((1L << n) - 1); + } + } + } + if (a0 < 0 && a0 != a) /* if neg. and it had fractional bits */ + a -= 1.0; /* adjust the floor */ + return a; /* return it */ +} diff --git a/reference/C/CONTRIB/SNIP/ll_msort.c b/reference/C/CONTRIB/SNIP/ll_msort.c new file mode 100755 index 0000000..4f78cdf --- /dev/null +++ b/reference/C/CONTRIB/SNIP/ll_msort.c @@ -0,0 +1,77 @@ +/* +** Here's an example of how to sort a singly-linked list. I think it +** can be modified to sort a doubly-linked list, but it would get a bit +** more complicated. Note that this is a recursive method, but the +** recursion depth is limited to be proportional to the base 2 log of +** the length of the list, so it won't "run away" and blow the stack. +** +** 10/21/93 rdg Fixed bug -- function was okay, but called incorrectly. +*/ + +/* linked list sort -- public domain by Ray Gardner 5/90 */ + +#include /* for NULL definition */ +#include + +typedef struct list_struct { + struct list_struct *next; + char *key; + /* other stuff */ + } list; + +/* returns < 0 if *p sorts lower than *q */ +int keycmp (list *p, list *q) +{ + return strcmp(p->key, q->key); +} + +/* merge 2 lists under dummy head item */ +list *lmerge (list *p, list *q) +{ + list *r, head; + + for ( r = &head; p && q; ) + { + if ( keycmp(p, q) < 0 ) + { + r = r->next = p; + p = p->next; + } + else + { + r = r->next = q; + q = q->next; + } + } + r->next = (p ? p : q); + return head.next; +} + +/* split list into 2 parts, sort each recursively, merge */ +list *lsort (list *p) +{ + list *q, *r; + + if ( p ) + { + q = p; + for ( r = q->next; r && (r = r->next) != NULL; r = r->next ) + q = q->next; + r = q->next; + q->next = NULL; + if ( r ) + p = lmerge(lsort(r), lsort(p)); + } + return p; +} + +main (void) +{ + list *listp; /* pointer to start of list */ + + /* first build unsorted list, then */ + + listp = lsort(listp); /* rdg 10/93 */ + + return 0; +} diff --git a/reference/C/CONTRIB/SNIP/ll_qsort.c b/reference/C/CONTRIB/SNIP/ll_qsort.c new file mode 100755 index 0000000..74cc8e7 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/ll_qsort.c @@ -0,0 +1,146 @@ +/*========== SNIP SNIP SNIP ==========*/ +/* SORT.H */ + +void *sortl(void *list, void *(*getnext)(void *), + void (*setnext)(void *, void *), + int (*compare)(void *, void *)); + +/*========== SNIP SNIP SNIP ==========*/ +/* SORT.C */ +#include +#include "sort.h" + + +/* + This is a quicksort routine to be used to sort linked-lists + by Jon Guthrie. +*/ + +void *sortl(list, getnext, setnext, compare) +void *list, *(*getnext)(void *), (*setnext)(void *, void *); +int (*compare)(void *, void *); + +{ +void *low_list, *high_list, *current, *pivot, *temp; +int result; + + /* + Test for empty list. + */ + if(NULL == list) + return(NULL); + + /* + Find the first element that doesn't have the same value as the first + element. + */ + current = list; + do + { + current = getnext(current); + if(NULL == current) + return(list); + } while(0 == (result = compare(list, current))); + + /* + My pivot value is the lower of the two. This insures that the sort + will always terminate by guaranteeing that there will be at least one + member of both of the sublists. + */ + if(result > 0) + pivot = current; + else + pivot = list; + + /* Initialize the sublist pointers */ + low_list = high_list = NULL; + + /* + Now, separate the items into the two sublists + */ + current = list; + while(NULL != current) + { + temp = getnext(current); + if(compare(pivot, current) < 0) + { + /* add one to the high list */ + setnext(current, high_list); + high_list = current; + } + else + { + /* add one to the low list */ + setnext(current, low_list); + low_list = current; + } + current = temp; + } + + /* + And, recursively call the sort for each of the two sublists. + */ + low_list = sortl(low_list, getnext, setnext, compare); + high_list = sortl(high_list, getnext, setnext, compare); + + /* + Now, I have to put the "high" list after the end of the "low" list. + To do that, I first have to find the end of the "low" list... + */ + current = temp = low_list; + while(1) + { + current = getnext(current); + if(NULL == current) + break; + temp = current; + } + + /* + Then, I put the "high" list at the end of the low list + */ + setnext(temp, high_list); + return(low_list); +} + +/* mergesort linked lists by Ray Gardner */ +/* split list into 2 parts, sort each recursively, merge */ +void *sortl(p, getnext, setnext, compare) +void *p, *(*getnext)(void *), (*setnext)(void *, void *); +int (*compare)(void *, void *); +{ + void *q, *r, *head; + + if ( p ) { /* first split it */ + r = p; + for ( q = getnext(r); q && (q = getnext(q)) != NULL; q = getnext(q) ) + r = getnext(r); + q = getnext(r); + setnext(r, NULL); + if ( q ) { /* now sort each sublist */ + p = sortl(p, getnext, setnext, compare); + q = sortl(q, getnext, setnext, compare); + if ( compare(q, p) < 0 ) { /* smallest item becomes list head */ + head = q; + q = getnext(q); + } else { + head = p; + p = getnext(p); + } + for ( r = head; p && q; ) { /* now merge the lists under head */ + if ( keycmp(q, p) < 0 ) { + setnext(r, q); + r = q; + q = getnext(q); + } else { + setnext(r, p); + r = p; + p = getnext(p); + } + } + setnext(r, (p ? p : q)); /* append the leftovers */ + p = head; + } + } + return p; +} diff --git a/reference/C/CONTRIB/SNIP/log.c b/reference/C/CONTRIB/SNIP/log.c new file mode 100755 index 0000000..e306db9 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/log.c @@ -0,0 +1,216 @@ +/************************************************************************ +* LOG.C - Creates a ASCII file with time and date stamps for logging * +* hours. * +* * +* usage: LOG [IN][OUT][CALC] * +* IN - Creates an opening entry from which a "time spent" * +* is calculated. * +* OUT - Creates a closing entry and calculates * +* "time spent" for that entry. * +* CALC - Calculates total overall "time spent" for the * +* entire log. * +* * +* NOTES: I used seconds to do all the calculations. The other * +* time/date entries are for human readability. Some * +* enhancments can be done to this program. * +* i.e. Wage/Pay calculation, closing the log after a CALC * +* to insure log is not reused, tracking hours for individual * +* people, tracking hours for individual projects, etc. * +* * +* Public domain by Robert Sprawls. * +************************************************************************/ + +#include +#include +#include +#include +#include + +/* Define time file constants */ + +#define HOUR 3600 /* Number of seconds in an hour. */ +#define MINS 60 /* Number of seconds in a minute */ +#define IN_ENTRY 40 /* Size of an IN entry */ +#define SEC_OFF 4 /* Offset of seconds in an IN entry */ +#define HOUR_OFF 64 /* Offset of seconds in an "time spent" */ + /* calculated entry. */ + +/* Define values returned to DOS */ + +#define OK 0 /* Executed normally, nothing will be eched */ +#define OPENLOG 1 /* Attempted to log in while open entry in log */ +#define CLOSEDLOG 2 /* Attempted to log out while closed entry in log */ +#define FILE_ERROR 3 /* File access error. Just in case. */ +#define SEEK_ERROR 4 /* File positioning error */ +#define NOPARMS 5 /* No parameters supplied to program */ +#define INVALID 6 /* Invalid parameters */ + +void usage( void ); +long get_in_entry( FILE * ); +void fastforw( FILE * ); /* Oppisite of rewind(); */ +void quit( int ); + +char strbuf[ IN_ENTRY + 1 ]; +FILE *wrklog; + +int main( int argc, char *argv[] ) +{ + char outline[ IN_ENTRY * 2 + 1 ]; + long in_entry_time = 0, total_seconds = 0; + double hours, pay; + time_t current_time; + div_t hdiv, mdiv; + + if( argc < 2 ) + { + usage(); + quit( NOPARMS ); + } + + /* Open log. Can be any directory. */ + if(( wrklog = fopen( "WORK.LOG", "a+" )) == NULL ) + quit( FILE_ERROR ); + + strupr( argv[ 1 ] ); + + time( ¤t_time ); + + /* Create an opening IN entry. */ + if( strcmp( "IN", argv[ 1 ] ) == 0 ) + { + /* Make sure there isn't a open entry already. */ + if( get_in_entry( wrklog ) ) + quit( OPENLOG ); + + /* Stamp it. */ + fprintf( wrklog, "%3s %ld %s", argv[ 1 ], current_time, + ctime( ¤t_time )); + } + /* Create a closinf OUT entry. */ + else if( strcmp( "OUT", argv[ 1 ] ) == 0 ) + { + /* Make sure there is a previous IN entry. */ + if( ( in_entry_time = get_in_entry( wrklog )) == 0 ) + quit( CLOSEDLOG ); + + total_seconds = current_time - in_entry_time; + sprintf( outline, "%3s %ld %s", argv[ 1 ], current_time, + ctime( ¤t_time )); + + /* Cut off the newline character that's normally put on. */ + outline[ strlen( outline ) - 1 ] = '\0'; + hdiv = div( total_seconds, HOUR ); + mdiv = div( hdiv.rem, MINS ); + + sprintf( strbuf, " Time Spent: %02d:%02d:%02d/%ld\n\n", + hdiv.quot, mdiv.quot, mdiv.rem, total_seconds ); + strcat( outline, strbuf ); + fprintf( wrklog, outline ); + } + /* Calculate the overall "time spent" */ + else if( strcmp( "CALC", argv[ 1 ] ) == 0 ) + { + rewind( wrklog ); + while( !feof( wrklog ) ) + { + /* This is to eliminate garbage or residual entries. */ + outline[ 0 ] = '\0'; + + fgets( outline, 80, wrklog ); + if( strstr( outline, "OUT" ) != NULL ) + { + total_seconds += atol( &outline[ HOUR_OFF ] ); + } + + } + + /* goto to end of file and stamp total hours */ + fastforw( wrklog ); + if( total_seconds ) + { + hdiv = div( total_seconds, HOUR ); + mdiv = div( hdiv.rem, MINS ); + fprintf( wrklog, "\t\t\t\t\t\t\t\t\t\t " + "Total Hours: %02d:%02d:%02d/%ld\n", + hdiv.quot, mdiv.quot, mdiv.rem, total_seconds ); + } + } + else + { + usage(); + quit( INVALID ); + } + + quit( OK ); +} + +void usage( void ) +{ + printf( "\nusage: LOG [IN][OUT][CALC]\n"); +} + +/**************************************************************** +* get_in_entry - gets a previous IN entry. * +* * +* Params: FILES *fp - file pointer. * +* Returns: The entry's seconds if successful, else 0 * +* * +* NOTES: If fseek fails for any reason, function does not * +* return. Instead, quit is call with the error code. * +****************************************************************/ + +long get_in_entry( FILE *fp ) +{ + + if( fseek( fp, -IN_ENTRY, SEEK_END ) != 0 ) + quit( SEEK_ERROR ); + + fread( strbuf, 1, IN_ENTRY, fp ); + fastforw( fp ); + + if( strstr( strbuf, "IN" ) == NULL ) + return( 0 ); + else + { + return( atol( &strbuf[ SEC_OFF ])); + } +} + +/**************************************************************** +* quit() - Program exit function. Reports of any outstanding * +* errors. * +* * +* Params: errcode - Error code as defined in beginning. * +* Returns: nothing. * +****************************************************************/ + +void quit( int errcode ) +{ + char *errmsg[] = + { + "", + "Log has an open entry.", + "No corresponding IN entry.", + "File open error.", + "Seek error", + "No parameters specified.", + "Invalid Parameters." + }; + + printf( "\n%s\n", errmsg[ errcode ] ); + + fclose( wrklog ); + exit( errcode ); +} + +/**************************************************************** +* fastforw() - Puts file pointer to end of file. * +* * +* Params: fp - File pointer. * +* Returns: nothing. * +****************************************************************/ + +void fastforw( FILE *fp ) +{ + fseek( fp, 0, SEEK_END ); +} diff --git a/reference/C/CONTRIB/SNIP/lsary.c b/reference/C/CONTRIB/SNIP/lsary.c new file mode 100755 index 0000000..1f62ad0 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/lsary.c @@ -0,0 +1,112 @@ +/* +** LSARY - A simple directory lister using a filename array +** A public domain C demo program by Bob Stout +*/ + +#include +#include +#include +#include +#include + +/* For portability, make everything look like MSC 6 */ + +#if defined(__TURBOC__) + #include + #define _dos_findfirst(f,a,b) findfirst(f,b,a) + #define _dos_findnext(b) findnext(b) + #define find_t ffblk + #ifndef _A_SUBDIR + #define _A_SUBDIR FA_DIREC + #endif + #define attrib ff_attrib + #define name ff_name + #define size ff_fsize + #define wr_time ff_ftime + #define wr_date ff_fdate + #define _dos_getdiskfree getdfree + #define diskfree_t dfree + #define avail_clusters df_avail + #define sectors_per_cluster df_sclus + #define bytes_per_sector df_bsec +#else /* assume MSC/QC */ + #include +#endif + +#ifdef TRUE + #undef TRUE +#endif +#ifdef FALSE + #undef FALSE +#endif +#ifdef ERROR + #undef ERROR +#endif + +enum LOGICAL {ERROR = -1, SUCCESS, FALSE = 0, TRUE}; + +#ifndef CAST + #define CAST(new_type,old_object) (*((new_type *)&(old_object))) +#endif + +#define LAST_CHAR(s) (((char *)s)[strlen(s) - 1]) + +struct DirEntry { + char fname[FILENAME_MAX]; + struct DirEntry *next; +} DirRoot = {"", NULL}; + +/* +** Read a directory into an array +*/ + +int ReaDirArray(char *path) +{ + struct find_t ff; + char pattern[67]; + struct DirEntry *base = &DirRoot; + + strcpy(pattern, path); + if ('/' != LAST_CHAR(pattern) && '\\' != LAST_CHAR(pattern)) + strcat(pattern, "\\"); + strcat(pattern, "*.*"); + if (SUCCESS == _dos_findfirst(pattern, 0xff, &ff)) do + { + struct DirEntry *node; + + if (NULL == (node = malloc(sizeof(struct DirEntry)))) + return ERROR; + base->next = node; + strcpy(base->fname, ff.name); + node->next = NULL; + *node->fname = '\0'; + base = node; + + } while (SUCCESS == _dos_findnext(&ff)); + return SUCCESS; +} + +/* +** Simple directory lister +*/ + +void main(int argc, char *argv[]) +{ + char *path; + + if (2 > argc) + path = "."; + else path = argv[1]; + if (ERROR == ReaDirArray(path)) + printf("*** Could not read %s\n", path); + else + { + struct DirEntry *node = &DirRoot; + printf("Directory of %s\n\n", path); + while (node) + { + puts(node->fname); + node = node->next; + } + } +} diff --git a/reference/C/CONTRIB/SNIP/lsd.c b/reference/C/CONTRIB/SNIP/lsd.c new file mode 100755 index 0000000..b416846 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/lsd.c @@ -0,0 +1,265 @@ +/* +** LSD - A simple directory lister +** A public domain C demo program by Bob Stout +*/ + +#include +#include +#include +#include +#include + +/* For portability, make everything look like MSC 6+ */ + +#if defined(__TURBOC__) + #include + #define _dos_findfirst(f,a,b) findfirst(f,b,a) + #define _dos_findnext(b) findnext(b) + #define find_t ffblk + #define _A_SUBDIR FA_DIREC + #define attrib ff_attrib + #define name ff_name + #define size ff_fsize + #define wr_time ff_ftime + #define wr_date ff_fdate + #define _dos_getdiskfree getdfree + #define diskfree_t dfree + #define avail_clusters df_avail + #define sectors_per_cluster df_sclus + #define bytes_per_sector df_bsec +#else /* assume MSC/QC */ + #include +#endif + +#ifdef TRUE + #undef TRUE +#endif +#ifdef FALSE + #undef FALSE +#endif +#ifdef ERROR + #undef ERROR +#endif + +enum LOGICAL {ERROR = -1, SUCCESS, FALSE = 0, TRUE}; + +#ifndef CAST + #define CAST(new_type,old_object) (*((new_type *)&(old_object))) +#endif + +#define LAST_CHAR(s) (((char *)s)[strlen(s) - 1]) + +struct DOS_TIME { + unsigned int ss : 5; + unsigned int mm : 6; + unsigned int hh : 5; + } ; +#define dos_time(t) CAST(struct DOS_TIME, (t)) + +struct DOS_DATE { + unsigned int da : 5; + unsigned int mo : 4; + unsigned int yr : 7; + } ; +#define dos_date(t) CAST(struct DOS_DATE, (t)) + +/* +** DOS DIR improved work-alike w/ improved formatting & attribute display +** +** supports /W switch +*/ + +main(int argc, char *argv[]) +{ + int i, files = 0, dirs = 0, argptr = 0, errflag = FALSE, cols, drive; + long siz_tot = 0L; + char *p, *fname, *ext, name[13], buf[67], numbuf[12]; + struct find_t ff; +#ifndef __ZTC__ + struct diskfree_t df; +#endif + int one_column(), five_column(); + int (*display)(char *, char *, long, unsigned, unsigned, unsigned) + = one_column; + char *sprintfc(char *, long); + char *capitalize(const char *); + + strcpy(buf, fname = "*.*"); + if(argc != 1) for (i = 1; i < argc; ++i) + { + if ('/' == argv[i][0]) + { + if ('W' == toupper(argv[i][1])) + display = five_column; + else + { + puts("\aUsage: LSD [/W] [file]"); + errflag = TRUE; + } + } + else if (!argptr) + argptr = i; + } + if (argptr) + { + fname = argv[argptr]; + strcpy(buf, fname); + if ('\\' == LAST_CHAR(buf) || ':' == LAST_CHAR(buf)) + strcat(buf, "*.*"); + else + { + if (SUCCESS == _dos_findfirst(buf, _A_SUBDIR, &ff)) + { + if (ff.attrib & _A_SUBDIR && '.' != *ff.name) + { + if ('\\' != LAST_CHAR(buf)) + strcat(buf, "\\"); + strcat(buf, "*.*"); + } + } + else errflag = TRUE; + } + } + if (':' == buf[1]) + drive = toupper(*buf) - '@'; + else drive = 0; + if (!errflag && !(_dos_findfirst(buf, 0xff, &ff))) do + { + siz_tot += ff.size; + if (ff.attrib & _A_SUBDIR) + ++dirs; + else ++files; + strcpy(name, ff.name); + if (NULL != (p = strchr(name, '.')) && p != name) + { + *p = '\0'; + ext = ++p; + } + else ext = ""; + cols = (*display)(name, ext, ff.size, + ff.attrib, ff.wr_date, ff.wr_time); + } while (SUCCESS == _dos_findnext(&ff)); + else + { + fprintf(stderr, "Cannot do directory on '%s'\n", fname); + exit(-1); + } + if (cols) + fputc('\n', stdout); + sprintfc(numbuf,siz_tot); + printf("\n%3d Files totalling %s bytes\n", files, numbuf); + printf("%3d Director%s\n", dirs, (1 == dirs) ? "y" : "ies"); +#ifndef __ZTC__ + _dos_getdiskfree(drive, &df); + sprintfc(numbuf, (long)df.avail_clusters * df.sectors_per_cluster * + df.bytes_per_sector); +#else /* if ZTC */ + sprintfc(numbuf, dos_getdiskfreespace(drive)); +#endif + printf("%s bytes free\n", numbuf); + return 0; +} + +/* +** The single column directory entry display function +*/ + +int one_column(char *name, + char *ext, + long size, + unsigned attribs, + unsigned date, + unsigned time) +{ + register int i, mask; + static char *atr = "RHSVDA", szbuf[12]; + + sprintfc(szbuf, size); + printf("%-8s %-3s %12s ", capitalize(name), capitalize(ext), szbuf); + for (i = 0, mask = 1; i < 6; ++i, mask <<= 1) + { + if (attribs & mask) + fputc(atr[i], stdout); + else fputc('.' , stdout); + } + printf("%4d-%02d-%02d%4d:%02d:%02d\n", + dos_date(date).mo, + dos_date(date).da, + (dos_date(date).yr + 80) % 100, + dos_time(time).hh, + dos_time(time).mm, + dos_time(time).ss); + return 0; +} + +/* +** The five column directory entry display function +*/ + +int five_column(char *name, + char *ext, + long size, + unsigned attribs, + unsigned date, + unsigned time) +{ + static int cols = 0; + + printf("%-8s %-3s%s", capitalize(name), capitalize(ext), + (5 > ++cols) ? " " : ""); + if (0 == (cols %= 5)) + putchar('\n'); + return (cols); +} + +/* +** Display a long int using commas as thousands separators +*/ + +char *sprintfc(char *string, long num) +{ + if (num > 999999L) + { + sprintf(string, "%d,%03d,%03d", + (int)(num / 1000000L), + (int)((num % 1000000L) / 1000L), + (int)(num % 1000L)); + } + else + { + if (num > 999L) + { + sprintf(string, "%d,%03d", + (int)(num / 1000L), + (int)(num % 1000L)); + } + else sprintf(string, "%d", (int)num); + } + return string; +} + +/* +** Capitalize a name or extension in place +*/ + +char *capitalize(const char *string) +{ + int flag = 0; + char *ptr = (char *)string; + + do + { + if (isalpha(*ptr)) + { + if (flag) + *ptr = (char)tolower(*ptr); + else + { + flag = 1; + *ptr = (char)toupper(*ptr); + } + } + else flag = 0; + } while (*++ptr); + return (char *)string; +} diff --git a/reference/C/CONTRIB/SNIP/ltoa.c b/reference/C/CONTRIB/SNIP/ltoa.c new file mode 100755 index 0000000..a241e7b --- /dev/null +++ b/reference/C/CONTRIB/SNIP/ltoa.c @@ -0,0 +1,58 @@ +/* +** LTOA.C +** +** Converts a long integer to a string. +** +** Copyright 1988-90 by Robert B. Stout dba MicroFirm +** +** Released to public domain, 1991 +** +** Parameters: 1 - number to be converted +** 2 - buffer in which to build the converted string +** 3 - number base to use for conversion +** +** Returns: A character pointer to the converted string if +** successful, a NULL pointer if the number base specified +** is out of range. +*/ + +#include +#include + +#define BUFSIZE (sizeof(long) * 8 + 1) + +char *ltoa(long N, char *str, int base) +{ + register int i = 2; + long uarg; + char *tail, *head = str, buf[BUFSIZE]; + + if (36 < base || 2 > base) + base = 10; /* can only use 0-9, A-Z */ + tail = &buf[BUFSIZE - 1]; /* last character position */ + *tail-- = '\0'; + + if (10 == base && N < 0L) + { + *head++ = '-'; + uarg = -N; + } + else uarg = N; + + if (uarg) + { + for (i = 1; uarg; ++i) + { + register ldiv_t r; + + r = ldiv(uarg, base); + *tail-- = (char)(r.rem + ((9L < r.rem) ? + ('A' - 10L) : '0')); + uarg = r.quot; + } + } + else *tail-- = '0'; + + memcpy(head, ++tail, i); + return str; +} diff --git a/reference/C/CONTRIB/SNIP/ltostr.c b/reference/C/CONTRIB/SNIP/ltostr.c new file mode 100755 index 0000000..583426a --- /dev/null +++ b/reference/C/CONTRIB/SNIP/ltostr.c @@ -0,0 +1,57 @@ +/* +** LTOSTR.C -- routine and example program to convert a long int to +** the specified numeric base, from 2 to 36. +** +** Written by Thad Smith III, Boulder, CO. USA 9/06/91 +** and contributed to the Public Domain. +*/ + +#include + +char * /* addr of terminating null */ +ltostr ( + char *str, /* output string */ + long val, /* value to be converted */ + unsigned base) /* conversion base */ +{ + ldiv_t r; /* result of val / base */ + + if (base > 36) /* no conversion if wrong base */ + { + str = '\0'; + return str; + } + if (val < 0) *str++ = '-'; + r = ldiv (labs(val), base); + + /* output digits of val/base first */ + + if (r.quot > 0) str = ltostr (str, r.quot, base); + + /* output last digit */ + + *str++ = "0123456789abcdefghijklmnopqrstuvwxyz"[(int)r.rem]; + *str = '\0'; + return str; +} + +#include +main() +{ + char buf[100], line[100], *tail; + long v; + int inbase, outbase; + + for (;;) + { + printf ("inbase, value, outbase? "); + fgets (line, sizeof line, stdin); + sscanf (line, " %d%*[, ]%[^, ]%*[, ]%d", &inbase, buf, &outbase); + if (inbase == 0) + break; /* exit if first number 0 */ + v = strtol (buf, &tail, inbase); + ltostr (buf, v, outbase); + printf ("=%ld (10) = %s (%d).\n", v, buf, outbase); + }; + return 0; +} diff --git a/reference/C/CONTRIB/SNIP/lv1ws.c b/reference/C/CONTRIB/SNIP/lv1ws.c new file mode 100755 index 0000000..b029cfe --- /dev/null +++ b/reference/C/CONTRIB/SNIP/lv1ws.c @@ -0,0 +1,36 @@ +/* +** Originally published as part of the MicroFirm Function Library +** +** Copyright 1987-88, Robert B.Stout +** +** Subset version released to the public domain, 1992 +** +** Makes all whitespace single spaces. Passed a string, lv1ws() +** converts all multiple whitespace characters to single spaces. +*/ + +#include + +void lv1ws(char *str) +{ + char *ibuf = str, *obuf = str; + int i = 0, cnt = 0; + + while(*ibuf) + { + if(isspace(*ibuf) && cnt) + ibuf++; + else + { + if (!isspace(*ibuf)) + cnt = 0; + else + { + *ibuf = ' '; + cnt = 1; + } + obuf[i++] = *ibuf++; + } + } + obuf[i] = '\0'; +} diff --git a/reference/C/CONTRIB/SNIP/lzhuf.c b/reference/C/CONTRIB/SNIP/lzhuf.c new file mode 100755 index 0000000..f1c678b --- /dev/null +++ b/reference/C/CONTRIB/SNIP/lzhuf.c @@ -0,0 +1,646 @@ +/************************************************************** + lzhuf.c + written by Haruyasu Yoshizaki 1988/11/20 + some minor changes 1989/04/06 + comments translated by Haruhiko Okumura 1989/04/07 + getbit and getbyte modified 1990/03/23 by Paul Edwards + so that they would work on machines where integers are + not necessarily 16 bits (although ANSI guarantees a + minimum of 16). This program has compiled and run with + no errors under Turbo C 2.0, Power C, and SAS/C 4.5 + (running on an IBM mainframe under MVS/XA 2.2). Could + people please use YYYY/MM/DD date format so that everyone + in the world can know what format the date is in? + external storage of filesize changed 1990/04/18 by Paul Edwards to + Intel's "little endian" rather than a machine-dependant style so + that files produced on one machine with lzhuf can be decoded on + any other. "little endian" style was chosen since lzhuf + originated on PC's, and therefore they should dictate the + standard. + initialization of something predicting spaces changed 1990/04/22 by + Paul Edwards so that when the compressed file is taken somewhere + else, it will decode properly, without changing ascii spaces to + ebcdic spaces. This was done by changing the ' ' (space literal) + to 0x20 (which is the far most likely character to occur, if you + don't know what environment it will be running on. +**************************************************************/ +#include +#include +#include +#include + +FILE *infile, *outfile; +static unsigned long int textsize = 0, codesize = 0, printcount = 0; + +char wterr[] = "Can't write."; + +static void Error(char *message) +{ + printf("\n%s\n", message); + exit(EXIT_FAILURE); +} + +/********** LZSS compression **********/ + +#define N 4096 /* buffer size */ +#define F 60 /* lookahead buffer size */ +#define THRESHOLD 2 +#define NIL N /* leaf of tree */ + +unsigned char + text_buf[N + F - 1]; +static int match_position, match_length, + lson[N + 1], rson[N + 257], dad[N + 1]; + +static void InitTree(void) /* initialize trees */ +{ + int i; + + for (i = N + 1; i <= N + 256; i++) + rson[i] = NIL; /* root */ + for (i = 0; i < N; i++) + dad[i] = NIL; /* node */ +} + +static void InsertNode(int r) /* insert to tree */ +{ + int i, p, cmp; + unsigned char *key; + unsigned c; + + cmp = 1; + key = &text_buf[r]; + p = N + 1 + key[0]; + rson[r] = lson[r] = NIL; + match_length = 0; + for ( ; ; ) { + if (cmp >= 0) { + if (rson[p] != NIL) + p = rson[p]; + else { + rson[p] = r; + dad[r] = p; + return; + } + } else { + if (lson[p] != NIL) + p = lson[p]; + else { + lson[p] = r; + dad[r] = p; + return; + } + } + for (i = 1; i < F; i++) + if ((cmp = key[i] - text_buf[p + i]) != 0) + break; + if (i > THRESHOLD) { + if (i > match_length) { + match_position = ((r - p) & (N - 1)) - 1; + if ((match_length = i) >= F) + break; + } + if (i == match_length) { + if ((c = ((r - p) & (N-1)) - 1) < (unsigned)match_position) { + match_position = c; + } + } + } + } + dad[r] = dad[p]; + lson[r] = lson[p]; + rson[r] = rson[p]; + dad[lson[p]] = r; + dad[rson[p]] = r; + if (rson[dad[p]] == p) + rson[dad[p]] = r; + else + lson[dad[p]] = r; + dad[p] = NIL; /* remove p */ +} + +static void DeleteNode(int p) /* remove from tree */ +{ + int q; + + if (dad[p] == NIL) + return; /* not registered */ + if (rson[p] == NIL) + q = lson[p]; + else + if (lson[p] == NIL) + q = rson[p]; + else { + q = lson[p]; + if (rson[q] != NIL) { + do { + q = rson[q]; + } while (rson[q] != NIL); + rson[dad[q]] = lson[q]; + dad[lson[q]] = dad[q]; + lson[q] = lson[p]; + dad[lson[p]] = q; + } + rson[q] = rson[p]; + dad[rson[p]] = q; + } + dad[q] = dad[p]; + if (rson[dad[p]] == p) + rson[dad[p]] = q; + else + lson[dad[p]] = q; + dad[p] = NIL; +} + +/* Huffman coding */ + +#define N_CHAR (256 - THRESHOLD + F) + /* kinds of characters (character code = 0..N_CHAR-1) */ +#define T (N_CHAR * 2 - 1) /* size of table */ +#define R (T - 1) /* position of root */ +#define MAX_FREQ 0x8000 /* updates tree when the */ +typedef unsigned char uchar; + + +/* table for encoding and decoding the upper 6 bits of position */ + +/* for encoding */ +uchar p_len[64] = { + 0x03, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08 +}; + +uchar p_code[64] = { + 0x00, 0x20, 0x30, 0x40, 0x50, 0x58, 0x60, 0x68, + 0x70, 0x78, 0x80, 0x88, 0x90, 0x94, 0x98, 0x9C, + 0xA0, 0xA4, 0xA8, 0xAC, 0xB0, 0xB4, 0xB8, 0xBC, + 0xC0, 0xC2, 0xC4, 0xC6, 0xC8, 0xCA, 0xCC, 0xCE, + 0xD0, 0xD2, 0xD4, 0xD6, 0xD8, 0xDA, 0xDC, 0xDE, + 0xE0, 0xE2, 0xE4, 0xE6, 0xE8, 0xEA, 0xEC, 0xEE, + 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, + 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF +}; + +/* for decoding */ +uchar d_code[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, + 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, + 0x0C, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D, + 0x0E, 0x0E, 0x0E, 0x0E, 0x0F, 0x0F, 0x0F, 0x0F, + 0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11, + 0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13, + 0x14, 0x14, 0x14, 0x14, 0x15, 0x15, 0x15, 0x15, + 0x16, 0x16, 0x16, 0x16, 0x17, 0x17, 0x17, 0x17, + 0x18, 0x18, 0x19, 0x19, 0x1A, 0x1A, 0x1B, 0x1B, + 0x1C, 0x1C, 0x1D, 0x1D, 0x1E, 0x1E, 0x1F, 0x1F, + 0x20, 0x20, 0x21, 0x21, 0x22, 0x22, 0x23, 0x23, + 0x24, 0x24, 0x25, 0x25, 0x26, 0x26, 0x27, 0x27, + 0x28, 0x28, 0x29, 0x29, 0x2A, 0x2A, 0x2B, 0x2B, + 0x2C, 0x2C, 0x2D, 0x2D, 0x2E, 0x2E, 0x2F, 0x2F, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, +}; + +uchar d_len[256] = { + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, +}; + +unsigned freq[T + 1]; /* frequency table */ + +int prnt[T + N_CHAR]; /* pointers to parent nodes, except for the */ + /* elements [T..T + N_CHAR - 1] which are used to get */ + /* the positions of leaves corresponding to the codes. */ + +int son[T]; /* pointers to child nodes (son[], son[] + 1) */ + +unsigned getbuf = 0; +uchar getlen = 0; + +static int GetBit(void) /* get one bit */ +{ + unsigned i; + + while (getlen <= 8) { + if ((int)(i = getc(infile)) < 0) i = 0; + getbuf |= i << (8 - getlen); + getlen += 8; + } + i = getbuf; + getbuf <<= 1; + getlen--; + return (int)((i & 0x8000) >> 15); +} + +static int GetByte(void) /* get one byte */ +{ + unsigned i; + + while (getlen <= 8) { + if ((int)(i = getc(infile)) < 0) i = 0; + getbuf |= i << (8 - getlen); + getlen += 8; + } + i = getbuf; + getbuf <<= 8; + getlen -= 8; + return (int)((i & 0xff00) >> 8); +} + +unsigned putbuf = 0; +uchar putlen = 0; + +static void Putcode(int l, unsigned c) /* output c bits of code */ +{ + putbuf |= c >> putlen; + if ((putlen += l) >= 8) { + if (putc(putbuf >> 8, outfile) == EOF) { + Error(wterr); + } + if ((putlen -= 8) >= 8) { + if (putc(putbuf, outfile) == EOF) { + Error(wterr); + } + codesize += 2; + putlen -= 8; + putbuf = c << (l - putlen); + } else { + putbuf <<= 8; + codesize++; + } + } +} + + +/* initialization of tree */ + +static void StartHuff(void) +{ + int i, j; + + for (i = 0; i < N_CHAR; i++) { + freq[i] = 1; + son[i] = i + T; + prnt[i + T] = i; + } + i = 0; j = N_CHAR; + while (j <= R) { + freq[j] = freq[i] + freq[i + 1]; + son[j] = i; + prnt[i] = prnt[i + 1] = j; + i += 2; j++; + } + freq[T] = 0xffff; + prnt[R] = 0; +} + + +/* reconstruction of tree */ + +static void reconst(void) +{ + int i, j, k; + unsigned f, l; + + /* collect leaf nodes in the first half of the table */ + /* and replace the freq by (freq + 1) / 2. */ + j = 0; + for (i = 0; i < T; i++) { + if (son[i] >= T) { + freq[j] = (freq[i] + 1) / 2; + son[j] = son[i]; + j++; + } + } + /* begin constructing tree by connecting sons */ + for (i = 0, j = N_CHAR; j < T; i += 2, j++) { + k = i + 1; + f = freq[j] = freq[i] + freq[k]; + for (k = j - 1; f < freq[k]; k--); + k++; + l = (j - k) * 2; + memmove(&freq[k + 1], &freq[k], l); + freq[k] = f; + memmove(&son[k + 1], &son[k], l); + son[k] = i; + } + /* connect prnt */ + for (i = 0; i < T; i++) { + if ((k = son[i]) >= T) { + prnt[k] = i; + } else { + prnt[k] = prnt[k + 1] = i; + } + } +} + + +/* increment frequency of given code by one, and update tree */ + +static void update(int c) +{ + int i, j, k, l; + + if (freq[R] == MAX_FREQ) { + reconst(); + } + c = prnt[c + T]; + do { + k = ++freq[c]; + + /* if the order is disturbed, exchange nodes */ + if ((unsigned)k > freq[l = c + 1]) { + while ((unsigned)k > freq[++l]); + l--; + freq[c] = freq[l]; + freq[l] = k; + + i = son[c]; + prnt[i] = l; + if (i < T) prnt[i + 1] = l; + + j = son[l]; + son[l] = i; + + prnt[j] = c; + if (j < T) prnt[j + 1] = c; + son[c] = j; + + c = l; + } + } while ((c = prnt[c]) != 0); /* repeat up to root */ +} + +unsigned code, len; + +static void EncodeChar(unsigned c) +{ + unsigned i; + int j, k; + + i = 0; + j = 0; + k = prnt[c + T]; + + /* travel from leaf to root */ + do { + i >>= 1; + + /* if node's address is odd-numbered, choose bigger brother node */ + if (k & 1) i += 0x8000; + + j++; + } while ((k = prnt[k]) != R); + Putcode(j, i); + code = i; + len = j; + update(c); +} + +static void EncodePosition(unsigned c) +{ + unsigned i; + + /* output upper 6 bits by table lookup */ + i = c >> 6; + Putcode(p_len[i], (unsigned)p_code[i] << 8); + + /* output lower 6 bits verbatim */ + Putcode(6, (c & 0x3f) << 10); +} + +static void EncodeEnd(void) +{ + if (putlen) { + if (putc(putbuf >> 8, outfile) == EOF) { + Error(wterr); + } + codesize++; + } +} + +static int DecodeChar(void) +{ + unsigned c; + + c = son[R]; + + /* travel from root to leaf, */ + /* choosing the smaller child node (son[]) if the read bit is 0, */ + /* the bigger (son[]+1} if 1 */ + while (c < T) { + c += GetBit(); + c = son[c]; + } + c -= T; + update(c); + return (int)c; +} + +static int DecodePosition(void) +{ + unsigned i, j, c; + + /* recover upper 6 bits from table */ + i = GetByte(); + c = (unsigned)d_code[i] << 6; + j = d_len[i]; + + /* read lower 6 bits verbatim */ + j -= 2; + while (j--) { + i = (i << 1) + GetBit(); + } + return (int)(c | (i & 0x3f)); +} + +/* compression */ + +static void Encode(void) /* compression */ +{ + int i, c, len, r, s, last_match_length; + + fseek(infile, 0L, 2); + textsize = ftell(infile); + fputc((int)((textsize & 0xff)),outfile); + fputc((int)((textsize & 0xff00) >> 8),outfile); + fputc((int)((textsize & 0xff0000L) >> 16),outfile); + fputc((int)((textsize & 0xff000000L) >> 24),outfile); + if (ferror(outfile)) + Error(wterr); /* output size of text */ + if (textsize == 0) + return; + rewind(infile); + textsize = 0; /* rewind and re-read */ + StartHuff(); + InitTree(); + s = 0; + r = N - F; + for (i = s; i < r; i++) + text_buf[i] = 0x20; + for (len = 0; len < F && (c = getc(infile)) != EOF; len++) + text_buf[r + len] = (unsigned char)c; + textsize = len; + for (i = 1; i <= F; i++) + InsertNode(r - i); + InsertNode(r); + do { + if (match_length > len) + match_length = len; + if (match_length <= THRESHOLD) { + match_length = 1; + EncodeChar(text_buf[r]); + } else { + EncodeChar(255 - THRESHOLD + match_length); + EncodePosition(match_position); + } + last_match_length = match_length; + for (i = 0; i < last_match_length && + (c = getc(infile)) != EOF; i++) { + DeleteNode(s); + text_buf[s] = (unsigned char)c; + if (s < F - 1) + text_buf[s + N] = (unsigned char)c; + s = (s + 1) & (N - 1); + r = (r + 1) & (N - 1); + InsertNode(r); + } + if ((textsize += i) > printcount) { + printf("%12ld\r", textsize); + printcount += 1024; + } + while (i++ < last_match_length) { + DeleteNode(s); + s = (s + 1) & (N - 1); + r = (r + 1) & (N - 1); + if (--len) InsertNode(r); + } + } while (len > 0); + EncodeEnd(); + printf("In : %ld bytes\n", textsize); + printf("Out: %ld bytes\n", codesize); + printf("Out/In: %.3f\n", 1.0 * codesize / textsize); +} + +static void Decode(void) /* recover */ +{ + int i, j, k, r, c; + unsigned long int count; + + textsize = (fgetc(infile)); + textsize |= (fgetc(infile) << 8); + textsize |= (fgetc(infile) << 16); + textsize |= (fgetc(infile) << 24); + if (ferror(infile)) + Error("Can't read"); /* read size of text */ + if (textsize == 0) + return; + StartHuff(); + for (i = 0; i < N - F; i++) + text_buf[i] = 0x20; + r = N - F; + for (count = 0; count < textsize; ) { + c = DecodeChar(); + if (c < 256) { + if (putc(c, outfile) == EOF) { + Error(wterr); + } + text_buf[r++] = (unsigned char)c; + r &= (N - 1); + count++; + } else { + i = (r - DecodePosition() - 1) & (N - 1); + j = c - 255 + THRESHOLD; + for (k = 0; k < j; k++) { + c = text_buf[(i + k) & (N - 1)]; + if (putc(c, outfile) == EOF) { + Error(wterr); + } + text_buf[r++] = (unsigned char)c; + r &= (N - 1); + count++; + } + } + if (count > printcount) { + printf("%12ld\r", count); + printcount += 1024; + } + } + printf("%12ld\n", count); +} + +int main(int argc, char *argv[]) +{ + char *s; + + if (argc != 4) { + printf("'lzhuf e file1 file2' encodes file1 into file2.\n" + "'lzhuf d file2 file1' decodes file2 into file1.\n"); + return EXIT_FAILURE; + } + if ((s = argv[1], s[1] || strpbrk(s, "DEde") == NULL) + || (s = argv[2], (infile = fopen(s, "rb")) == NULL) + || (s = argv[3], (outfile = fopen(s, "wb")) == NULL)) { + printf("??? %s\n", s); + return EXIT_FAILURE; + } + if (toupper(*argv[1]) == 'E') + Encode(); + else + Decode(); + fclose(infile); + fclose(outfile); + return EXIT_SUCCESS; +} diff --git a/reference/C/CONTRIB/SNIP/mainmain.c b/reference/C/CONTRIB/SNIP/mainmain.c new file mode 100755 index 0000000..7bb36b9 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/mainmain.c @@ -0,0 +1 @@ +main(){char *c="main(){char *c=%c%s%c;printf(c,34,c,34);}";printf(c,34,c,34);} diff --git a/reference/C/CONTRIB/SNIP/make.ini b/reference/C/CONTRIB/SNIP/make.ini new file mode 100755 index 0000000..9914fdb --- /dev/null +++ b/reference/C/CONTRIB/SNIP/make.ini @@ -0,0 +1,190 @@ +# +# Master MAKE.INI file for NDMAKE +# +# jim nutt +# 'the computer handyman' +# + +.SUFFIXES : .doc .exe .prf .obj .cpp .c .a86 .asm .com .a86 + +# +# generate response files for these as well as lib and link +# + +.RESPONSE_LINK: tlink blink ztcmap +.RESPONSE_LIB: tlib zorlib + +VPATH = .;c:\include; +MAKE_TMP= $(TMP) + +# +# some defaults +# + +project = +obj = +cc = ztc +mcflags = $p $s $w +cflags = + +# +# zortech c settings +# + +ztclib = c:\lib\$(cc) # where are the libraries +ztcinclude = c:\include\$(cc) +ztclibrary = $(lib)\zl$(model) +ztccompile = $(cc) -c -m$(options) +ztcoptions = $(model) $(mcflags) -I$(include) -ic:\include +ztcstartup = +ztcwild = +ztcscheck = -s +ztcpcheck = +ztcalign = -a +ztcunsigned= -J +ztccodeview= -g +ztcmaxwarnings= -p -r +ztcinline = -f +ztcoptimize= -o+all -o+loop +ztcmodel = -m +ztcdefine = -d +ztcstdc = -A + +# +# quick c settings +# + +qcllib = c:\lib\msc +qclinclude = c:\include\msc +qcllibrary = $(lib)\$(model)libcr $(lib)\libh +qclcompile = qcl /c /X /Zl /A$(options) /D__MSC__=1 +qcloptions = $(model) $(mcflags) /I$(include) +qclstartup = +qclwild = +qclscheck = +qclpcheck = /Zr +qclalign = /Zp +qclunsigned= +qclcodeview= /Zi +qclmaxwarnings = /W3 +qclinline = /FPi87 +qcloptimize= /Ox +qclmodel = /A +qcldefine = /D +qclstdc = /Za + +# +# msc 5.1 settings +# + +msclib = c:\lib\msc +mscinclude = c:\include\$(cc) +msclibrary = $(lib)\$(model)libcr $(lib)\libh +msccompile = cl /c /X /Zl /A$(options) /D__MSC__=1 +mscoptions = $(model) $(mcflags) /I$(include) /Ic:\include +mscstartup = +mscwild = +mscscheck = +mscpcheck = +mscalign = /Zp +mscunsigned= +msccodeview= /Zi +mscmaxwarnings = /W3 +mscinline = /FPi87 +mscoptimize= /Owilt +mscmodel = /A +mscdefine = /D +mscstdc = /Za + +# +# turbo c settings +# + +tcclib = c:\lib\$(cc) # where are the libraries +tccinclude = c:\include\$(cc) +tcclibrary = $(lib)\c$(model) +tcccompile = $(cc) -c -m$(options) +tccoptions = $(model) $(mcflags) -I$(include) +tccstartup = $(lib)\c0$(model) +tccwild = +tccscheck = -N +tccpcheck = +tccalign = -a- +tccunsigned= -K +tcccodeview= -y +tccmaxwarnings = -w -w-stv +tccinline = -f87 +tccmodel = -m +tccdefine = -D +tccoptimize= -O -G -r +tccstdc = -A + +lib = $($(cc)lib) +include = $($(cc)include) +library = $($(cc)library) +cxl = $(lib)\cxl$(model) +options = $($(cc)options) +compile = $($(cc)compile) $(cflags) +startup = $($(cc)startup) +wild = $($(cc)wild) +libs = $(library) + +# compiler options + +a = $($(cc)align) # byte align structures +c = $($(cc)codeview) # codeview debugging (if avail, else symdeb) +d = $($(cc)define) # command line #define +i = $($(cc)inline) # inline 8087 code generation +m = $($(cc)model) # memory model selection +p = $($(cc)pcheck) # pointer checking (if available) +s = $($(cc)scheck) # turn on stack checking +u = $($(cc)unsigned) # chars are unsigned +o = $($(cc)optimize) # do max optimizations +w = $($(cc)maxwarnings) # give maximum warnings +stdc = $($(cc)stdc) # use ANSI standard keywords only + +model = S + +# the linker + +linkopt = /noi +linker = link + +# an easy linking macros + +linklst = $($(project)obj),$(project),$(project),$(libs) $(linkopt); +link = $(linker) $(wild) $(startup) $(linklst) + +# default rules + +markfile : + calltree -z markfile *.c + +.c.exe : + .c.obj + $(linker) $(wild) $(startup) $*, $* ,$* ,$(libs) $(linkopt); + +.obj.exe : + $(link) + +.c.obj : + $(compile) $*.c + +.cpp.obj : + $(cc) $* + +.asm.obj : + masm $*; + +.a86.obj : + a86 +o +s $*.a86 $*.obj + +.a86.com : + a86 $*.a86 + +.a86.exe : + a86 +o +s $*.a86 + link $*; + +.prf.doc : + proff $*.prf $*.doc diff --git a/reference/C/CONTRIB/SNIP/match.c b/reference/C/CONTRIB/SNIP/match.c new file mode 100755 index 0000000..55e1229 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/match.c @@ -0,0 +1,585 @@ +/* + EPSHeader + + File: match.c + Author: J. Kercheval + Created: Sat, 01/05/1991 22:21:49 +*/ +/* + EPSRevision History + + J. Kercheval Wed, 02/20/1991 22:29:01 Released to Public Domain + J. Kercheval Fri, 02/22/1991 15:29:01 fix '\' bugs (two :( of them) + J. Kercheval Sun, 03/10/1991 19:31:29 add error return to matche() + J. Kercheval Sun, 03/10/1991 20:11:11 add is_valid_pattern code + J. Kercheval Sun, 03/10/1991 20:37:11 beef up main() + J. Kercheval Tue, 03/12/1991 22:25:10 Released as V1.1 to Public Domain +*/ + +/* + Wildcard Pattern Matching +*/ + + +#include "match.h" + +int matche_after_star (register char *pattern, register char *text); +int fast_match_after_star (register char *pattern, register char *text); + +/*---------------------------------------------------------------------------- +* +* Return TRUE if PATTERN has any special wildcard characters +* +----------------------------------------------------------------------------*/ + +BOOLEAN is_pattern (char *p) +{ + while (*p) + { + switch (*p++) + { + case '?': + case '*': + case '[': + case '\\': + return TRUE; + } + } + return FALSE; +} + + +/*---------------------------------------------------------------------------- +* +* Return TRUE if PATTERN has is a well formed regular expression according +* to the above syntax +* +* error_type is a return code based on the type of pattern error. Zero is +* returned in error_type if the pattern is a valid one. error_type return +* values are as follows: +* +* PATTERN_VALID - pattern is well formed +* PATTERN_ESC - pattern has invalid escape ('\' at end of pattern) +* PATTERN_RANGE - [..] construct has a no end range in a '-' pair (ie [a-]) +* PATTERN_CLOSE - [..] construct has no end bracket (ie [abc-g ) +* PATTERN_EMPTY - [..] construct is empty (ie []) +* +----------------------------------------------------------------------------*/ + +BOOLEAN is_valid_pattern (char *p, int *error_type) +{ + /* init error_type */ + *error_type = PATTERN_VALID; + + /* loop through pattern to EOS */ + while (*p) + { + /* determine pattern type */ + switch (*p) + { + /* check literal escape, it cannot be at end of pattern */ + case '\\': + if (!*++p) + { + *error_type = PATTERN_ESC; + return FALSE; + } + p++; + break; + + /* the [..] construct must be well formed */ + case '[': + p++; + + /* if the next character is ']' then bad pattern */ + if (*p == ']') + { + *error_type = PATTERN_EMPTY; + return FALSE; + } + + /* if end of pattern here then bad pattern */ + if (!*p) + { + *error_type = PATTERN_CLOSE; + return FALSE; + } + + /* loop to end of [..] construct */ + while (*p != ']') + { + /* check for literal escape */ + if (*p == '\\') + { + p++; + + /* if end of pattern here then bad pattern */ + if (!*p++) + { + *error_type = PATTERN_ESC; + return FALSE; + } + } + else p++; + + /* if end of pattern here then bad pattern */ + if (!*p) + { + *error_type = PATTERN_CLOSE; + return FALSE; + } + + /* if this a range */ + if (*p == '-') + { + /* we must have an end of range */ + if (!*++p || *p == ']') + { + *error_type = PATTERN_RANGE; + return FALSE; + } + else + { + + /* check for literal escape */ + if (*p == '\\') + p++; + + /* if end of pattern here + then bad pattern */ + if (!*p++) + { + *error_type = PATTERN_ESC; + return FALSE; + } + } + } + } + break; + + /* all other characters are valid pattern elements */ + case '*': + case '?': + default: + p++; /* "normal" character */ + break; + } + } + return TRUE; +} + + +/*---------------------------------------------------------------------------- +* +* Match the pattern PATTERN against the string TEXT; +* +* returns MATCH_VALID if pattern matches, or an errorcode as follows +* otherwise: +* +* MATCH_PATTERN - bad pattern +* MATCH_LITERAL - match failure on literal mismatch +* MATCH_RANGE - match failure on [..] construct +* MATCH_ABORT - premature end of text string +* MATCH_END - premature end of pattern string +* MATCH_VALID - valid match +* +* +* A match means the entire string TEXT is used up in matching. +* +* In the pattern string: +* `*' matches any sequence of characters (zero or more) +* `?' matches any character +* [SET] matches any character in the specified set, +* [!SET] or [^SET] matches any character not in the specified set. +* +* A set is composed of characters or ranges; a range looks like +* character hyphen character (as in 0-9 or A-Z). [0-9a-zA-Z_] is the +* minimal set of characters allowed in the [..] pattern construct. +* Other characters are allowed (ie. 8 bit characters) if your system +* will support them. +* +* To suppress the special syntactic significance of any of `[]*?!^-\', +* and match the character exactly, precede it with a `\'. +* +----------------------------------------------------------------------------*/ + +int matche (register char *p, register char *t) +{ + register char range_start, range_end; /* start and end in range */ + + BOOLEAN invert; /* is this [..] or [!..] */ + BOOLEAN member_match; /* have I matched the [..] construct? */ + BOOLEAN loop; /* should I terminate? */ + + for ( ; *p; p++, t++) + { + /* if this is the end of the text + then this is the end of the match */ + + if (!*t) + { + return ( *p == '*' && *++p == '\0' ) ? + MATCH_VALID : MATCH_ABORT; + } + + /* determine and react to pattern type */ + + switch (*p) + { + case '?': /* single any character match */ + break; + + case '*': /* multiple any character match */ + return matche_after_star (p, t); + + /* [..] construct, single member/exclusion character match */ + case '[': + { + /* move to beginning of range */ + + p++; + + /* check if this is a member match or exclusion match */ + + invert = FALSE; + if (*p == '!' || *p == '^') + { + invert = TRUE; + p++; + } + + /* if closing bracket here or at range start then we have a + malformed pattern */ + + if (*p == ']') + { + return MATCH_PATTERN; + } + + member_match = FALSE; + loop = TRUE; + + while (loop) + { + /* if end of construct then loop is done */ + + if (*p == ']') + { + loop = FALSE; + continue; + } + + /* matching a '!', '^', '-', '\' or a ']' */ + + if (*p == '\\') + { + range_start = range_end = *++p; + } + else range_start = range_end = *p; + + /* if end of pattern then bad pattern (Missing ']') */ + + if (!*p) + return MATCH_PATTERN; + + /* check for range bar */ + if (*++p == '-') + { + /* get the range end */ + + range_end = *++p; + + /* if end of pattern or construct + then bad pattern */ + + if (range_end == '\0' || range_end == ']') + return MATCH_PATTERN; + + /* special character range end */ + if (range_end == '\\') + { + range_end = *++p; + + /* if end of text then + we have a bad pattern */ + if (!range_end) + return MATCH_PATTERN; + } + + /* move just beyond this range */ + p++; + } + + /* if the text character is in range then match found. + make sure the range letters have the proper + relationship to one another before comparison */ + + if (range_start < range_end) + { + if (*t >= range_start && *t <= range_end) + { + member_match = TRUE; + loop = FALSE; + } + } + else + { + if (*t >= range_end && *t <= range_start) + { + member_match = TRUE; + loop = FALSE; + } + } + } + + /* if there was a match in an exclusion set then no match */ + /* if there was no match in a member set then no match */ + + if ((invert && member_match) || !(invert || member_match)) + return MATCH_RANGE; + + /* if this is not an exclusion then skip the rest of + the [...] construct that already matched. */ + + if (member_match) + { + while (*p != ']') + { + /* bad pattern (Missing ']') */ + if (!*p) + return MATCH_PATTERN; + + /* skip exact match */ + if (*p == '\\') + { + p++; + + /* if end of text then + we have a bad pattern */ + + if (!*p) + return MATCH_PATTERN; + } + + /* move to next pattern char */ + + p++; + } + } + break; + } + case '\\': /* next character is quoted and must match exactly */ + + /* move pattern pointer to quoted char and fall through */ + + p++; + + /* if end of text then we have a bad pattern */ + + if (!*p) + return MATCH_PATTERN; + + /* must match this character exactly */ + + default: + if (*p != *t) + return MATCH_LITERAL; + } + } + /* if end of text not reached then the pattern fails */ + + if (*t) + return MATCH_END; + else return MATCH_VALID; +} + + +/*---------------------------------------------------------------------------- +* +* recursively call matche() with final segment of PATTERN and of TEXT. +* +----------------------------------------------------------------------------*/ + +int matche_after_star (register char *p, register char *t) +{ + register int match = 0; + register nextp; + + /* pass over existing ? and * in pattern */ + + while ( *p == '?' || *p == '*' ) + { + /* take one char for each ? and + */ + + if (*p == '?') + { + /* if end of text then no match */ + if (!*t++) + return MATCH_ABORT; + } + + /* move to next char in pattern */ + + p++; + } + + /* if end of pattern we have matched regardless of text left */ + + if (!*p) + return MATCH_VALID; + + /* get the next character to match which must be a literal or '[' */ + + nextp = *p; + if (nextp == '\\') + { + nextp = p[1]; + + /* if end of text then we have a bad pattern */ + + if (!nextp) + return MATCH_PATTERN; + } + + /* Continue until we run out of text or definite result seen */ + + do + { + /* a precondition for matching is that the next character + in the pattern match the next character in the text or that + the next pattern char is the beginning of a range. Increment + text pointer as we go here */ + + if (nextp == *t || nextp == '[') + match = matche(p, t); + + /* if the end of text is reached then no match */ + + if (!*t++) + match = MATCH_ABORT; + + } while ( match != MATCH_VALID && + match != MATCH_ABORT && + match != MATCH_PATTERN); + + /* return result */ + + return match; +} + + +/*---------------------------------------------------------------------------- +* +* match() is a shell to matche() to return only BOOLEAN values. +* +----------------------------------------------------------------------------*/ + +BOOLEAN match( char *p, char *t ) +{ + int error_type; + + error_type = matche(p,t); + return (error_type == MATCH_VALID ) ? TRUE : FALSE; +} + + +#ifdef TEST + +/* +** This test main expects as first arg the pattern and as second arg +** the match string. Output is yaeh or nay on match. If nay on +** match then the error code is parsed and written. +*/ + +#include + +int main(int argc, char *argv[]) +{ + int error; + int is_valid_error; + + if (argc != 3) + printf("Usage: MATCH Pattern Text\n"); + else + { + printf("Pattern: %s\n", argv[1]); + printf("Text : %s\n", argv[2]); + + if (!is_pattern(argv[1])) + printf(" First Argument Is Not A Pattern\n"); + else + { + error = matche(argv[1],argv[2]); + is_valid_pattern(argv[1],&is_valid_error); + + switch (error) + { + case MATCH_VALID: + printf(" Match Successful"); + if (is_valid_error != PATTERN_VALID) + printf(" -- is_valid_pattern() " + "is complaining\n"); + else printf("\n"); + break; + + case MATCH_LITERAL: + printf(" Match Failed on Literal\n"); + break; + + case MATCH_RANGE: + printf(" Match Failed on [..]\n"); + break; + + case MATCH_ABORT: + printf(" Match Failed on Early " + "Text Termination\n"); + break; + + case MATCH_END: + printf(" Match Failed on Early " + "Pattern Termination\n"); + break; + + case MATCH_PATTERN: + switch (is_valid_error) + { + case PATTERN_VALID: + printf(" Internal Disagreement " + "On Pattern\n"); + break; + + case PATTERN_ESC: + printf(" Literal Escape at " + "End of Pattern\n"); + break; + + + case PATTERN_RANGE: + printf(" No End of Range in " + "[..] Construct\n"); + break; + + case PATTERN_CLOSE: + printf(" [..] Construct is Open\n"); + break; + + case PATTERN_EMPTY: + printf(" [..] Construct is Empty\n"); + break; + + default: + printf(" Internal Error in " + "is_valid_pattern()\n"); + } + break; + + default: + printf(" Internal Error in matche()\n"); + break; + } + } + } + return(0); +} + +#endif diff --git a/reference/C/CONTRIB/SNIP/match.doc b/reference/C/CONTRIB/SNIP/match.doc new file mode 100755 index 0000000..96d783b --- /dev/null +++ b/reference/C/CONTRIB/SNIP/match.doc @@ -0,0 +1,126 @@ + + REGEX Globber (Wild Card Matching) + + A *IX SH style pattern matcher written in C + V1.10 Dedicated to the Public Domain + + March 12, 1991 + J. Kercheval + [72450,3702] -- johnk@wrq.com + + + + +*IX SH style Regular Expressions +================================ + +The *IX command SH is a working shell similar in feel to the MSDOS +shell COMMAND.COM. In point of fact much of what we see in our +familiar DOS PROMPT was gleaned from the early UNIX shells available +for many of machines the people involved in the computing arena had +at the time of the development of DOS and it's much maligned +precursor CP/M (although the UNIX shells were and are much more +flexible and powerful then those on the current flock of micro +machines). The designers of DOS and CP/M did some fairly strange +things with their command processor and OS. One of those things was +to only selectively adopt the regular expressions allowed within the +*IX shells. Only '?' and '*' were allowed in filenames and even with +these the '*' was allowed only at the end of a pattern and in fact +when used to specify the filename the '*' did not apply to extension. +This gave rise to the all too common expression "*.*". + +REGEX Globber is a SH pattern matcher. This allows such +specifications as *75.zip or * (equivelant to *.* in DOS lingo). +Expressions such as [a-e]*t would fit the name "apple.crt" or +"catspaw.bat" or "elegant". This allows considerably wider +flexibility in file specification, general parsing or any other +circumstance in which this type of pattern matching is wanted. + +A match would mean that the entire string TEXT is used up in matching +the PATTERN and conversely the matched TEXT uses up the entire +PATTERN. + +In the specified pattern string: + `*' matches any sequence of characters (zero or more) + `?' matches any character + `\' suppresses syntactic significance of a special character + [SET] matches any character in the specified set, + [!SET] or [^SET] matches any character not in the specified set. + +A set is composed of characters or ranges; a range looks like +'character hyphen character' (as in 0-9 or A-Z). [0-9a-zA-Z_] is the +minimal set of characters allowed in the [..] pattern construct. +Other characters are allowed (ie. 8 bit characters) if your system +will support them (it almost certainly will). + +To suppress the special syntactic significance of any of `[]*?!^-\', +and match the character exactly, precede it with a `\'. + +To view several examples of good and bad patterns and text see the +output of MATCHTST.BAT + + + +MATCH() and MATCHE() +==================== + +The match module as written has two parsing routines, one is matche() +and the other is match(). Since match() is a call to matche() which +simply has its output mapped to a BOOLEAN value (ie TRUE if pattern +matches or FALSE otherwise), I will concentrate my explanations here +on matche(). + +The purpose of matche() is to match a pattern against a string of +text (usually a file name or specification). The match routine has +extensive pattern validity checking built into it as part of the +parser and allows for a robust pattern match. + +The parser gives an error code on return of type int. The error code +will be one of the the following defined values (defined in match.h): + + MATCH_PATTERN - bad pattern or misformed pattern + MATCH_LITERAL - match failed on character match (standard + character) + MATCH_RANGE - match failure on character range ([..] construct) + MATCH_ABORT - premature end of text string (pattern longer + than text string) + MATCH_END - premature end of pattern string (text longer + than pattern called for) + MATCH_VALID - valid match using pattern + +The functions are declared as follows: + + BOOLEAN match (char *pattern, char *text); + + int matche(register char *pattern, register char *text); + + + +IS_VALID_PATTERN() and IS_PATTERN() +=================================== + +There are two routines for determining properties of a pattern +string. The first, is_pattern(), is designed simply to determine if +some character exists within the text which is consistent with a SH +regular expression (this function returns TRUE if so and FALSE if +not). The second, is_valid_pattern() is designed to check the +validity of a given pattern string (TRUE return if valid, FALSE if +not). By 'validity', I mean well formed or syntactically correct. + +In addition, is_valid_pattern() has as one of it's parameters a +return code for determining the type of error found in the pattern if +one exists. The error codes are as follows and defined in match.h: + + PATTERN_VALID - pattern is well formed + PATTERN_ESC - pattern has invalid literal escape ('\' at end of + pattern) + PATTERN_RANGE - [..] construct has a no end range in a '-' pair + (ie [a-]) + PATTERN_CLOSE - [..] construct has no end bracket (ie [abc-g ) + PATTERN_EMPTY - [..] construct is empty (ie []) + +The functions are declared as follows: + + BOOLEAN is_valid_pattern (char *pattern, int *error_type); + + BOOLEAN is_pattern (char *pattern); diff --git a/reference/C/CONTRIB/SNIP/match.h b/reference/C/CONTRIB/SNIP/match.h new file mode 100755 index 0000000..a2ee6b6 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/match.h @@ -0,0 +1,107 @@ +/* + EPSHeader + + File: match.h + Author: J. Kercheval + Created: Sat, 01/05/1991 22:27:18 +*/ +/* + EPSRevision History + + J. Kercheval Wed, 02/20/1991 22:28:37 Released to Public Domain + J. Kercheval Sun, 03/10/1991 18:02:56 add is_valid_pattern + J. Kercheval Sun, 03/10/1991 18:25:48 add error_type in is_valid_pattern + J. Kercheval Sun, 03/10/1991 18:47:47 error return from matche() + J. Kercheval Tue, 03/12/1991 22:24:49 Released as V1.1 to Public Domain +*/ + +/* + Wildcard Pattern Matching +*/ + +#ifndef BOOLEAN +# define BOOLEAN int +# define TRUE 1 +# define FALSE 0 +#endif + +/* match defines */ +#define MATCH_PATTERN 6 /* bad pattern */ +#define MATCH_LITERAL 5 /* match failure on literal match */ +#define MATCH_RANGE 4 /* match failure on [..] construct */ +#define MATCH_ABORT 3 /* premature end of text string */ +#define MATCH_END 2 /* premature end of pattern string */ +#define MATCH_VALID 1 /* valid match */ + +/* pattern defines */ +#define PATTERN_VALID 0 /* valid pattern */ +#define PATTERN_ESC -1 /* literal escape at end of pattern */ +#define PATTERN_RANGE -2 /* malformed range in [..] construct */ +#define PATTERN_CLOSE -3 /* no end bracket in [..] construct */ +#define PATTERN_EMPTY -4 /* [..] contstruct is empty */ + +/*---------------------------------------------------------------------------- +* +* Match the pattern PATTERN against the string TEXT; +* +* match() returns TRUE if pattern matches, FALSE otherwise. +* matche() returns MATCH_VALID if pattern matches, or an errorcode +* as follows otherwise: +* +* MATCH_PATTERN - bad pattern +* MATCH_LITERAL - match failure on literal mismatch +* MATCH_RANGE - match failure on [..] construct +* MATCH_ABORT - premature end of text string +* MATCH_END - premature end of pattern string +* MATCH_VALID - valid match +* +* +* A match means the entire string TEXT is used up in matching. +* +* In the pattern string: +* `*' matches any sequence of characters (zero or more) +* `?' matches any character +* [SET] matches any character in the specified set, +* [!SET] or [^SET] matches any character not in the specified set. +* +* A set is composed of characters or ranges; a range looks like +* character hyphen character (as in 0-9 or A-Z). [0-9a-zA-Z_] is the +* minimal set of characters allowed in the [..] pattern construct. +* Other characters are allowed (ie. 8 bit characters) if your system +* will support them. +* +* To suppress the special syntactic significance of any of `[]*?!^-\', +* and match the character exactly, precede it with a `\'. +* +----------------------------------------------------------------------------*/ + +BOOLEAN match (char *pattern, char *text); + +int matche(register char *pattern, register char *text); + +/*---------------------------------------------------------------------------- +* +* Return TRUE if PATTERN has any special wildcard characters +* +----------------------------------------------------------------------------*/ + +BOOLEAN is_pattern (char *pattern); + +/*---------------------------------------------------------------------------- +* +* Return TRUE if PATTERN has is a well formed regular expression according +* to the above syntax +* +* error_type is a return code based on the type of pattern error. Zero is +* returned in error_type if the pattern is a valid one. error_type return +* values are as follows: +* +* PATTERN_VALID - pattern is well formed +* PATTERN_ESC - pattern has invalid escape ('\' at end of pattern) +* PATTERN_RANGE - [..] construct has a no end range in a '-' pair (ie [a-]) +* PATTERN_CLOSE - [..] construct has no end bracket (ie [abc-g ) +* PATTERN_EMPTY - [..] construct is empty (ie []) +* +----------------------------------------------------------------------------*/ + +BOOLEAN is_valid_pattern (char *pattern, int *error_type); diff --git a/reference/C/CONTRIB/SNIP/maze_1.c b/reference/C/CONTRIB/SNIP/maze_1.c new file mode 100755 index 0000000..8746357 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/maze_1.c @@ -0,0 +1,183 @@ +/* + This program makes 10x10 mazes and prints them on the screen. No + promise of portability is made, but it does seem to work on NS GNX + C. + + Public Domain by Jonathan Guthrie. +*/ + +#include +#include +#include + +#define UP 1 +#define DN 2 +#define LT 4 +#define RT 8 + +int addelem(int, int [12][12], int *, int, int); +void openwall(int [12][12], int, int); +void writemaze(int [12][12]); + +void main(void) +{ + int i, j, base; + int search[150], array[12][12]; + + for(i=1 ; i<11 ; ++i) + { + array[i][0] = -1; + array[i][11] = -1; + array[0][i] = -1; + array[11][i] = -1; + for(j=1 ; j<11 ; ++j) + array[i][j] = 0; + } + + srand((int)time(NULL)); + i = rand() % 10 + 1; + j = rand() % 10 + 1; + base = addelem(0, array, search, i, j); + array[i][j] = RT + RT; /* Not a valid value */ + while(0 < base) + { + i = rand() % base; + j = search[i]; + search[i] = search[--base]; + i = j % 100; + j /= 100; + openwall(array, i, j); + base = addelem(base, array, search, i, j); + } + + writemaze(array); +} + + +int addelem(int base, int maze[12][12], int *search, int row, int col) +{ + if(0 == maze[row-1][col]) + { + search[base++] = row + col * 100 - 1; + maze[row-1][col] = -DN; + } + else if(0 > maze[row-1][col]) + maze[row-1][col] -= DN; + + if(0 == maze[row+1][col]) + { + search[base++] = row + col * 100 + 1; + maze[row+1][col] = -UP; + } + else if(0 > maze[row+1][col]) + maze[row+1][col] -= UP; + + if(0 == maze[row][col-1]) + { + search[base++] = row + col * 100 - 100; + maze[row][col-1] = -RT; + } + else if(0 > maze[row][col-1]) + maze[row][col-1] -= RT; + + if(0 == maze[row][col+1]) + { + search[base++] = row + col * 100 + 100; + maze[row][col+1] = -LT; + } + else if(0 > maze[row][col+1]) + maze[row][col+1] -= LT; + + return base; +} + + +void openwall(int maze[12][12], int row, int col) +{ + int directions, max, direction, temprow, tempcol, temp, back; + + directions = -maze[row][col]; + + max = 0; + if(directions & UP) + { + temp = rand(); + if(temp > max) + { + max = temp; + direction = UP; + back = DN; + temprow = row - 1; + tempcol = col; + } + } + + if(directions & DN) + { + temp = rand(); + if(temp > max) + { + max = temp; + direction = DN; + back = UP; + temprow = row + 1; + tempcol = col; + } + } + + if(directions & LT) + { + temp = rand(); + if(temp > max) + { + max = temp; + direction = LT; + back = RT; + temprow = row; + tempcol = col - 1; + } + } + + if(directions & RT) + { + temp = rand(); + if(temp > max) + { + max = temp; + direction = RT; + back = LT; + temprow = row; + tempcol = col + 1; + } + } + + maze[row][col] = direction; + maze[temprow][tempcol] += back; +} + +void writemaze(int maze[12][12]) +{ + int i, j; + + puts("*********************"); + for(i=1 ; i<11 ; ++i) + { + putchar('*'); + for(j=1 ; j<11 ; ++j) + { + putchar(' '); + if(maze[i][j] & RT) + putchar(' '); + else putchar('*'); + } + putchar('\n'); + for(j=1 ; j<11 ; ++j) + { + putchar('*'); + if(maze[i][j] & DN) + putchar(' '); + else putchar('*'); + } + puts("*"); + } +} diff --git a/reference/C/CONTRIB/SNIP/maze_2.c b/reference/C/CONTRIB/SNIP/maze_2.c new file mode 100755 index 0000000..75b12f3 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/maze_2.c @@ -0,0 +1 @@ +int a[1817];main(z,p,q,r){for(p=80;q+p-80;p-=2*a[p])for(z=9;z--;)q=3&(r=time(0)+r*57)/7,q=q?q-1?q-2?1-p%79?-1:0:p%79-77?1:0:p<1659?79:0:p>158?-79:0,q?!a[p+q*2]?a[p+=a[p+=q]=q]=q:0:0;for(;q++-1817;)printf(q%79?"%c":"%c\n"," #"[!a[q-1]]);} diff --git a/reference/C/CONTRIB/SNIP/maze_3.c b/reference/C/CONTRIB/SNIP/maze_3.c new file mode 100755 index 0000000..fbc2ac9 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/maze_3.c @@ -0,0 +1,7 @@ +char*M,A,Z,E=40,J[40],T[40];main(C){for(*J=A=scanf(M="%d",&C); +-- E; J[ E] =T +[E ]= E) printf("._"); for(;(A-=Z=!Z) || (printf("\n|" +) , A = 39 ,C -- +) ; Z || printf (M ))M[Z]=Z[A-(E =A[J-Z])&&!C +& A == T[ A] +|6<<11 +#include +#include +#include + +#ifdef __TURBOC__ + #include + #define FAR far +#else + #include + #define FAR _far +#endif + +#if !defined(MK_FP) + #define MK_FP(seg,off) ((void FAR *)(((long)(seg) << 16)|(unsigned)(off))) +#endif + +struct EnvRec { + unsigned EnvSeg; /*Segment of the environment*/ + unsigned EnvLen; /*Usable length of the environment*/ + } EnvRec; + +struct EnvRec *MasterEnv(void) +{ + unsigned owner; + unsigned mcb; + unsigned eseg; + static struct EnvRec env; + + env.EnvSeg = env.EnvLen = 0; + owner = * ((unsigned FAR *) MK_FP(0, (2+4*0x2e))); + + /* int 0x2e points to command.com */ + + mcb = owner -1; + + /*Mcb points to memory control block for COMMAND */ + + if ( (*((char FAR *) MK_FP(mcb, 0)) != 'M') && + (*((unsigned FAR *) MK_FP(mcb, 1)) != owner) ) + return (struct EnvRec *) 0; + + eseg = *((unsigned FAR *) MK_FP(owner, 0x2c)); + + /* Read segment of environment from PSP of COMMAND} */ + /* Earlier versions of DOS don't store environment segment there */ + + if ( !eseg ) + { + + /* Master environment is next block past COMMAND */ + + mcb = owner + *((unsigned FAR *) MK_FP(mcb, 3)); + if ( (*((char FAR *) MK_FP(mcb, 0)) != 'M') && + (*((unsigned FAR *) MK_FP(mcb, 1)) != owner) ) + return (struct EnvRec *) 0; + eseg = mcb + 1; + } + else mcb = eseg-1; + + /* Return segment and length of environment */ + + env.EnvSeg = eseg; + env.EnvLen = *((unsigned FAR *) MK_FP(mcb, 3)) << 4 ; + return &env; +} + +/* +** Then a function to find the string to be replaced. This one'll +** return a pointer to the string, or a pointer to the first (of 2) +** NUL byte at the end of the environment. +*/ + +char FAR *SearchEnv( char FAR *eptr, char *search ) +{ + char FAR *e; + char *s; + while ( *eptr ) + { + for ( s=search, e=eptr; *e && *s && (*e == *s); e++, s++ ) + ; /* NULL STATEMENT */ + if ( !*s ) + break; + while ( *eptr ) + eptr++; /* position to the NUL byte */ + eptr++; /* next string */ + } + return eptr; +} + +/* +** Now, the function to replace, add or delete. If a value is not +** given, the string is deleted. +*/ + +int SetEnvStr( struct EnvRec *env, char *search, char *value ) +{ + /* -Set environment string, returning true if successful */ + + char FAR *envptr; + register char FAR *p; + char *s; + int newlen; + int oldlen; + int i; + + if ( !env->EnvSeg || !search ) + return 0; + + /* get some memory for complete environment string */ + + newlen = strlen(search) + sizeof((char) '\0') + strlen(value) + 2; + if ( (s = (char *) malloc( newlen)) == NULL ) + return 0; + for ( i = 0; *search; search++, i++ ) + s[i] = *search; + s[i++] = '='; + s[i] = '\0'; + envptr = SearchEnv((char FAR *) MK_FP(env->EnvSeg, 0), s ); + if ( *envptr ) + { + for ( p = envptr, oldlen = 0; *p; oldlen++, p++ ) + ; /* can't use strlen() because of far pointer */ + } /* will set p to point to terminating NUL */ + + if ( *value && (newlen > (int)env->EnvLen) ) /* not a deletion */ + { + free( s ); + return 0; /* won't fit */ + } + + if ( *envptr ) /* shift it down */ + { + for ( ++p; (*p || *(p+1)); envptr++, p++ ) + *envptr = *p; + *envptr++ = '\0'; + *envptr = '\0'; + } + if ( *value ) /* append it */ + { + strcat(s, value); + while ( *s ) + *(envptr++) = *s++; + *envptr++ = '\0'; + *envptr = '\0'; + } + free(s); + return 1; +} + +/* +** Ok, just to show you that I tested it : +*/ + +void main(void) +{ + char vn[80]; + char va[80]; + struct EnvRec *p = MasterEnv(); + + puts("enter variable name:"); + gets(vn); + puts("enter value:"); + gets(va); + printf("SetEnvStr returned %d\n", SetEnvStr( p, strupr(vn), va) ); +} diff --git a/reference/C/CONTRIB/SNIP/mdalloc.c b/reference/C/CONTRIB/SNIP/mdalloc.c new file mode 100755 index 0000000..171d464 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/mdalloc.c @@ -0,0 +1,160 @@ +/* Written by Blair Haukedal 91/09 and placed in the public domain */ + +/* mdalloc - a multi dimensional array allocator + * mdfree - a companion function to mdalloc for freeing storage + * synopsis: + * void *mdalloc(int ndim, int width, ...); + * where: ndim: number of array dimensions + * width: size of elements in array + * variable args are dimensions of array + * returns: n-way indirect pointer to allocated storage + * or NULL if insufficient storage + * + * void mdfree(void *p, ndim); + * where: p: pointer to storage obtained by mdalloc + * ndim: number of dimensions used in mdalloc + * + * example: + * int ***tip; + * tip = mdalloc(3, sizeof(int), 2, 3, 4); + * tip will be a triple indirect pointer to a 3 dimensional array + * tip[0][0][0] refers to the first int in a contiguous area of + * storage that is 2*3*4*sizeof(int) bytes long + * tip[0][0] is the address of the first int + * memset can be used to initialize array elements as follows: + * memset(tip[0][0], 0, 2*3*4*sizeof(int)); + * mdfree is used to free storage obtained with mdalloc: + * mdfree(tip, 3) + * + * notes: + * - must be compiled with appropriate memory model + * - memory is allocated for each dimension for indirect pointers + * eg. 3x4x5 array of longs + * (assuming 4 byte longs, small mem model) + * p = mdalloc(3, sizeof(long), 3, 4, 5) - bytes + * 3 pointers allocated for 1st dimension - 6 + * 3x4 pointers allocated for 2nd dimension - 24 + * 3x4x5 longs allocated for array elements - 240 + * total of 270 bytes allocated + * - if insufficient memory, nothing will be allocated. + * ie. intermediate pointer arrays that were successfully + * allocated will be freed. + * - the intent of mdalloc is to facilitate dynamic array creation, + * it will use more memory than statically declared arrays, and + * the required dereferencing will be slower than the use of + * statically declared arrays. + * - this function assumes that sizeof(char) == 1. + */ + +#include +#include + +static void **md2(int n_units, int ndim, int *dims); +static void md3(char ***tip, int n_units, int ndim, int *dims); + +static int w_units; + +/* mdalloc: entry point for mdalloc function described above + * - reduces variable arg list to fixed list with last arg + * represented as pointer to int (array dimensions). + * Calls md2 to allocate storage. + * Calls md3 to initialize intermediate pointers. + * Returns pointer. + */ + +void *mdalloc(int ndim, int width, ...) +{ + va_list argp; + int *dims, i; + char ***tip; + + va_start(argp, width); + + /* allocate storage for variable args (dimensions) */ + + dims = malloc(ndim*sizeof(int)); + if(dims == NULL) + return NULL; + + /* initialize dimensions array for subsequent calls */ + + for(i=0; i1 && tip) + md3(tip, dims[0], ndim-1, &dims[1]); /* init pointers */ + + free(dims); + return tip; +} + +/* mdfree: companion function to mdalloc + * frees storage obtained by mdalloc + */ + +void mdfree(void *tip, int ndim) +{ + if(ndim == 1) + free(tip); + else + { + mdfree(((void **)tip)[0], ndim-1); + free(tip); + } +} + +/* md2: allocates storage for n-way indirect pointer arrays + * allocates storage for requested array elements + */ + +static void **md2(int n_units, int ndim, int *dims) +{ + char **tip; + + if(ndim == 1) + /* recursed to final dimension - allocate element storage */ + tip = malloc(n_units*w_units); + else + { + /* allocate pointer array for dimension n */ + tip = malloc(n_units*sizeof(char *)); + if(tip) + { + /* recurse until final dimension */ + tip[0] = (char *)md2(n_units*dims[0], ndim-1, &dims[1]); + if(tip[0] == NULL) + { + /* allocate error - fall back up freeing everything */ + free(tip); + tip = NULL; + } + } + } + return (void **)tip; +} + +/* md3: initializes indirect pointer arrays */ + +static void md3(char ***tip, int n_units, int ndim, int *dims) +{ + int i; + + for(i=1; i 1) + /* not at final dimension - continue to recurse */ + md3((char ***)tip[0], n_units*dims[0], ndim-1, &dims[1]); +} diff --git a/reference/C/CONTRIB/SNIP/mem.c b/reference/C/CONTRIB/SNIP/mem.c new file mode 100755 index 0000000..493ae2b --- /dev/null +++ b/reference/C/CONTRIB/SNIP/mem.c @@ -0,0 +1,681 @@ +/* +** This is a copyrighted work which is functionally identical to work +** originally published in Micro Cornucopia magazine (issue #52, March-April, +** 1990) and is freely licensed by the author, Walter Bright, for any use. +*/ + +/*_ mem.c Fri Jan 26 1990 Modified by: Walter Bright */ +/* $Header: /home/cvs/c_cpp_reference/reference/C/CONTRIB/SNIP/mem.c,v 1.1.1.1 2000/02/24 23:01:18 tasin Exp $ */ +/* Memory management package */ + +#if defined(VAX11C) +#define __FILE__ "mem.c" +#endif + +#include +#include +#include + +#ifndef MEM_H +#include "mem.h" +#endif + +#ifndef assert +#include +#endif + +#if defined(_MSC_VER) +#include +#endif + +#if !defined(VAX11C) +#ifdef BSDUNIX +#include +#else +#include +#endif +#else +extern char *strcpy(),*memcpy(); +extern int strlen(); +#endif /* VAX11C */ + +int mem_inited = 0; /* != 0 if initialized */ + +static int mem_behavior = MEM_ABORTMSG; +static int (*fp)() = NULL; /* out-of-memory handler */ +static int mem_count; /* # of allocs that haven't been free'd */ +static int mem_scount; /* # of sallocs that haven't been free'd */ +static int near mem_exception(); /* called when out of memory */ + +/* Determine where to send error messages */ +#ifdef MSDOS +#define ferr stdout /* stderr can't be redirected with MS-DOS */ +#else +#define ferr stderr +#endif + +/*******************************/ + +void mem_setexception(flag,handler_fp) +#if __cplusplus +enum MEM_E flag; +#else +int flag; +#endif +int (*handler_fp)(); +{ + mem_behavior = flag; + fp = (mem_behavior == MEM_CALLFP) ? handler_fp : 0; +#if MEM_DEBUG + assert(0 <= flag && flag <= MEM_RETRY); +#endif +} + +/************************* + * This is called when we're out of memory. + * Returns: + * 1: try again to allocate the memory + * 0: give up and return NULL + */ + +static int near mem_exception() +{ int behavior; + + behavior = mem_behavior; + while (1) + { + switch (behavior) + { + case MEM_ABORTMSG: +#if defined(MSDOS) || defined(__OS2__) + /* Avoid linking in buffered I/O */ + { static char msg[] = "Fatal error: out of memory\r\n"; + + write(1,msg,sizeof(msg) - 1); + } +#else + fputs("Fatal error: out of memory\n",ferr); +#endif + /* FALL-THROUGH */ + case MEM_ABORT: + exit(EXIT_FAILURE); + /* NOTREACHED */ + case MEM_CALLFP: + assert(fp); + behavior = (*fp)(); + break; + case MEM_RETNULL: + return 0; + case MEM_RETRY: + return 1; + default: + assert(0); + } + } +} + +/****************************/ + +#if MEM_DEBUG + +#undef mem_strdup + +char *mem_strdup(s) +const char *s; +{ + return mem_strdup_debug(s,__FILE__,__LINE__); +} + +char *mem_strdup_debug(s,file,line) +char *file; +const char *s; +int line; +{ + char *p; + + p = s + ? (char *) mem_malloc_debug((unsigned) strlen(s) + 1,file,line) + : NULL; + return p ? strcpy(p,s) : p; +} +#else +char *mem_strdup(s) +const char *s; +{ + char *p; + + p = s ? (char *) mem_malloc((unsigned) strlen(s) + 1) : NULL; + return p ? strcpy(p,s) : p; +} + +#endif /* MEM_DEBUG */ + +#ifdef MEM_DEBUG + +static long mem_maxalloc; /* max # of bytes allocated */ +static long mem_numalloc; /* current # of bytes allocated */ + +#define BEFOREVAL 0x12345678 /* value to detect underrun */ +#define AFTERVAL 0x87654321 /* value to detect overrun */ + +#if SUN || SUN386 +static long afterval = AFTERVAL; /* so we can do &afterval */ +#endif + +/* The following should be selected to give maximum probability that */ +/* pointers loaded with these values will cause an obvious crash. On */ +/* Unix machines, a large value will cause a segment fault. */ +/* MALLOCVAL is the value to set malloc'd data to. */ + +#if MSDOS || __OS2__ +#define BADVAL 0xFF +#define MALLOCVAL 0xEE +#else +#define BADVAL 0x7A +#define MALLOCVAL 0xEE +#endif + +/* Disable mapping macros */ +#undef mem_malloc +#undef mem_calloc +#undef mem_realloc +#undef mem_free + +/* Create a list of all alloc'ed pointers, retaining info about where */ +/* each alloc came from. This is a real memory and speed hog, but who */ +/* cares when you've got obscure pointer bugs. */ + +static struct mem_debug +{ struct mh + { struct mem_debug *Mnext; /* next in list */ + struct mem_debug *Mprev; /* previous value in list */ + char *Mfile; /* filename of where allocated */ + int Mline; /* line number of where allocated */ + unsigned Mnbytes; /* size of the allocation */ + long Mbeforeval; /* detect underrun of data */ + } m; + char data[1]; /* the data actually allocated */ +} mem_alloclist = +{ + { (struct mem_debug *) NULL, + (struct mem_debug *) NULL, + "noname", + 11111, + 0, + BEFOREVAL + }, + AFTERVAL +}; + +/* Convert from a void *to a mem_debug struct. */ +#define mem_ptrtodl(p) ((struct mem_debug *) ((char *)p - sizeof(struct mh))) + +/* Convert from a mem_debug struct to a mem_ptr. */ +#define mem_dltoptr(dl) ((void *) &((dl)->data[0])) + +#define next m.Mnext +#define prev m.Mprev +#define file m.Mfile +#define line m.Mline +#define nbytes m.Mnbytes +#define beforeval m.Mbeforeval + +/***************************** + * Set new value of file,line + */ + +void mem_setnewfileline(ptr,fil,lin) +void *ptr; +char *fil; +int lin; +{ + struct mem_debug *dl; + + dl = mem_ptrtodl(ptr); + dl->file = fil; + dl->line = lin; +} + +/**************************** + * Print out struct mem_debug. + */ + +static void near mem_printdl(dl) +struct mem_debug *dl; +{ +#if LPTR + fprintf(ferr,"alloc'd from file '%s' line %d nbytes %d ptr x%lx\n", + dl->file,dl->line,dl->nbytes,mem_dltoptr(dl)); +#else + fprintf(ferr,"alloc'd from file '%s' line %d nbytes %d ptr x%x\n", + dl->file,dl->line,dl->nbytes,mem_dltoptr(dl)); +#endif +} + +/**************************** + * Print out file and line number. + */ + +static void near mem_fillin(fil,lin) +char *fil; +int lin; +{ + fprintf(ferr,"File '%s' line %d\n",fil,lin); + fflush(ferr); +} + +/**************************** + * If MEM_DEBUG is not on for some modules, these routines will get + * called. + */ + +void *mem_calloc(u) +unsigned u; +{ + return mem_calloc_debug(u,__FILE__,__LINE__); +} + +void *mem_malloc(u) +unsigned u; +{ + return mem_malloc_debug(u,__FILE__,__LINE__); +} + +void *mem_realloc(p,u) +void *p; +unsigned u; +{ + return mem_realloc_debug(p,u,__FILE__,__LINE__); +} + +void mem_free(p) +void *p; +{ + mem_free_debug(p,__FILE__,__LINE__); +} + + +/**************************/ + +void mem_freefp(p) +void *p; +{ + mem_free(p); +} + +/*********************** + * Debug versions of mem_calloc(), mem_free() and mem_realloc(). + */ + +void *mem_malloc_debug(n,fil,lin) +unsigned n; +char *fil; +int lin; +{ void *p; + + p = mem_calloc_debug(n,fil,lin); + if (p) + memset(p,MALLOCVAL,n); + return p; +} + +void *mem_calloc_debug(n,fil,lin) +unsigned n; +char *fil; +int lin; +{ + struct mem_debug *dl; + + do + dl = (struct mem_debug *) + calloc(sizeof(*dl) + n + sizeof(AFTERVAL) - 1,1); + while (dl == NULL && mem_exception()); + if (dl == NULL) + { +#if 0 + printf("Insufficient memory for alloc of %d at ",n); + mem_fillin(fil,lin); + printf("Max allocated was: %ld\n",mem_maxalloc); +#endif + return NULL; + } + dl->file = fil; + dl->line = lin; + dl->nbytes = n; + dl->beforeval = BEFOREVAL; +#if SUN || SUN386 /* bus error if we store a long at an odd address */ + memcpy(&(dl->data[n]),&afterval,sizeof(AFTERVAL)); +#else + *(long *) &(dl->data[n]) = AFTERVAL; +#endif + + /* Add dl to start of allocation list */ + dl->next = mem_alloclist.next; + dl->prev = &mem_alloclist; + mem_alloclist.next = dl; + if (dl->next != NULL) + dl->next->prev = dl; + + mem_count++; + mem_numalloc += n; + if (mem_numalloc > mem_maxalloc) + mem_maxalloc = mem_numalloc; + return mem_dltoptr(dl); +} + +void mem_free_debug(ptr,fil,lin) +void *ptr; +char *fil; +int lin; +{ + struct mem_debug *dl; + + if (ptr == NULL) + return; +#if 0 + { fprintf(ferr,"Freeing NULL pointer at "); + goto err; + } +#endif + if (mem_count <= 0) + { fprintf(ferr,"More frees than allocs at "); + goto err; + } + dl = mem_ptrtodl(ptr); + if (dl->beforeval != BEFOREVAL) + { +#if LPTR + fprintf(ferr,"Pointer x%lx underrun\n",ptr); +#else + fprintf(ferr,"Pointer x%x underrun\n",ptr); +#endif + goto err2; + } +#if SUN || SUN386 /* Bus error if we read a long from an odd address */ + if (memcmp(&dl->data[dl->nbytes],&afterval,sizeof(AFTERVAL)) != 0) +#else + if (*(long *) &dl->data[dl->nbytes] != AFTERVAL) +#endif + { +#if LPTR + fprintf(ferr,"Pointer x%lx overrun\n",ptr); +#else + fprintf(ferr,"Pointer x%x overrun\n",ptr); +#endif + goto err2; + } + mem_numalloc -= dl->nbytes; + if (mem_numalloc < 0) + { fprintf(ferr,"error: mem_numalloc = %ld, dl->nbytes = %d\n", + mem_numalloc,dl->nbytes); + goto err2; + } + + /* Remove dl from linked list */ + if (dl->prev) + dl->prev->next = dl->next; + if (dl->next) + dl->next->prev = dl->prev; + + /* Stomp on the freed storage to help detect references */ + /* after the storage was freed. */ + memset((void *) dl,BADVAL,sizeof(*dl) + dl->nbytes); + mem_count--; + + /* Some compilers can detect errors in the heap. */ +#if defined(DLC) + { int i; + i = free(dl); + assert(i == 0); + } +#else + free((void *) dl); +#endif + return; + +err2: + mem_printdl(dl); +err: + fprintf(ferr,"free'd from "); + mem_fillin(fil,lin); + assert(0); + /* NOTREACHED */ +} + +/******************* + * Debug version of mem_realloc(). + */ + +void *mem_realloc_debug(oldp,n,fil,lin) +void *oldp; +unsigned n; +char *fil; +int lin; +{ void *p; + struct mem_debug *dl; + + if (n == 0) + { mem_free_debug(oldp,fil,lin); + p = NULL; + } + else if (oldp == NULL) + p = mem_malloc_debug(n,fil,lin); + else + { + p = mem_malloc_debug(n,fil,lin); + if (p != NULL) + { + dl = mem_ptrtodl(oldp); + if (dl->nbytes < n) + n = dl->nbytes; + memcpy(p,oldp,n); + mem_free_debug(oldp,fil,lin); + } + } + return p; +} + +/***************************/ + +void mem_check() +{ register struct mem_debug *dl; + + for (dl = mem_alloclist.next; dl != NULL; dl = dl->next) + mem_checkptr(mem_dltoptr(dl)); +} + +/***************************/ + +void mem_checkptr(p) +register void *p; +{ register struct mem_debug *dl; + + for (dl = mem_alloclist.next; dl != NULL; dl = dl->next) + { + if (p >= (void *) &(dl->data[0]) && + p < (void *)((char *)dl + sizeof(struct mem_debug)-1 + dl->nbytes)) + goto L1; + } + assert(0); + +L1: + dl = mem_ptrtodl(p); + if (dl->beforeval != BEFOREVAL) + { +#if LPTR + fprintf(ferr,"Pointer x%lx underrun\n",p); +#else + fprintf(ferr,"Pointer x%x underrun\n",p); +#endif + goto err2; + } +#if SUN || SUN386 /* Bus error if we read a long from an odd address */ + if (memcmp(&dl->data[dl->nbytes],&afterval,sizeof(AFTERVAL)) != 0) +#else + if (*(long *) &dl->data[dl->nbytes] != AFTERVAL) +#endif + { +#if LPTR + fprintf(ferr,"Pointer x%lx overrun\n",p); +#else + fprintf(ferr,"Pointer x%x overrun\n",p); +#endif + goto err2; + } + return; + +err2: + mem_printdl(dl); + assert(0); +} + +#else + +/***************************/ + +void *mem_malloc(numbytes) +unsigned numbytes; +{ void *p; + + if (numbytes == 0) + return NULL; + while (1) + { + p = malloc(numbytes); + if (p == NULL) + { if (mem_exception()) + continue; + } + else + mem_count++; + break; + } + /*printf("malloc(%d) = x%lx\n",numbytes,p);*/ + return p; +} + +/***************************/ + +void *mem_calloc(numbytes) +unsigned numbytes; +{ void *p; + + if (numbytes == 0) + return NULL; + while (1) + { + p = calloc(numbytes,1); + if (p == NULL) + { if (mem_exception()) + continue; + } + else + mem_count++; + break; + } + /*printf("calloc(%d) = x%lx\n",numbytes,p);*/ + return p; +} + +/***************************/ + +void *mem_realloc(oldmem_ptr,newnumbytes) +void *oldmem_ptr; +unsigned newnumbytes; +{ void *p; + + if (oldmem_ptr == NULL) + p = mem_malloc(newnumbytes); + else if (newnumbytes == 0) + { mem_free(oldmem_ptr); + p = NULL; + } + else + { + do + p = realloc(oldmem_ptr,newnumbytes); + while (p == NULL && mem_exception()); + } + /*printf("realloc(x%lx,%d) = x%lx\n",oldmem_ptr,newnumbytes,p);*/ + return p; +} + +/***************************/ + +void mem_free(ptr) +void *ptr; +{ + /*printf("free(x%lx)\n",ptr);*/ + if (ptr != NULL) + { assert(mem_count > 0); + mem_count--; +#if DLC + { int i; + + i = free(ptr); + assert(i == 0); + } +#else + free(ptr); +#endif + } +} + +#endif /* MEM_DEBUG */ + +/***************************/ + +void mem_init() +{ + if (mem_inited == 0) + { mem_count = 0; +#if MEM_DEBUG + mem_numalloc = 0; + mem_maxalloc = 0; + mem_alloclist.next = NULL; +#endif +#if defined(__ZTC__) || defined(__SC__) + /* Necessary if mem_sfree() calls free() before any */ + /* calls to malloc(). */ + free(malloc(1)); /* initialize storage allocator */ +#endif + mem_inited++; + } +} + +/***************************/ + +void mem_term() +{ + + if (mem_inited) + { +#if MEM_DEBUG + register struct mem_debug *dl; + + for (dl = mem_alloclist.next; dl; dl = dl->next) + { fprintf(ferr,"Unfreed pointer: "); + mem_printdl(dl); + } +#if 0 + fprintf(ferr,"Max amount ever allocated == %ld bytes\n", + mem_maxalloc); +#endif +#else + if (mem_count) + fprintf(ferr,"%d unfreed items\n",mem_count); + if (mem_scount) + fprintf(ferr,"%d unfreed s items\n",mem_scount); +#endif /* MEM_DEBUG */ + assert(mem_count == 0 && mem_scount == 0); + mem_inited = 0; + } +} + +#undef next +#undef prev +#undef file +#undef line +#undef nbytes +#undef beforeval + diff --git a/reference/C/CONTRIB/SNIP/mem.h b/reference/C/CONTRIB/SNIP/mem.h new file mode 100755 index 0000000..d40ad25 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/mem.h @@ -0,0 +1,212 @@ +/* +** This is a copyrighted work which is functionally identical to work +** originally published in Micro Cornucopia magazine (issue #52, March-April, +** 1990) and is freely licensed by the author, Walter Bright, for any use. +*/ + +/*_ mem.h Fri May 26 1989 Modified by: Walter Bright */ +/* $Header: /home/cvs/c_cpp_reference/reference/C/CONTRIB/SNIP/mem.h,v 1.1.1.1 2000/02/24 23:01:19 tasin Exp $ */ +/* Copyright 1986-1988 by Northwest Software */ +/* All Rights Reserved */ +/* Written by Walter Bright */ + +#ifndef MEM_H +#define MEM_H 1 + +#ifndef TOOLKIT_H +#include "toolkit.h" +#endif + +/* + * Memory management routines. + * + * Compiling: + * + * #define MEM_DEBUG 1 when compiling to enable extended debugging + * features. + * + * Features always enabled: + * + * o mem_init() is called at startup, and mem_term() at + * close, which checks to see that the number of alloc's is + * the same as the number of free's. + * o Behavior on out-of-memory conditions can be controlled + * via mem_setexception(). + * + * Extended debugging features: + * + * o Enabled by #define MEM_DEBUG 1 when compiling. + * o Check values are inserted before and after the alloc'ed data + * to detect pointer underruns and overruns. + * o Free'd pointers are checked against alloc'ed pointers. + * o Free'd storage is cleared to smoke out references to free'd data. + * o Realloc'd pointers are always changed, and the previous storage + * is cleared, to detect erroneous dependencies on the previous + * pointer. + * o The routine mem_checkptr() is provided to check an alloc'ed + * pointer. + */ + +/********************* GLOBAL VARIABLES *************************/ + +extern int mem_inited; /* != 0 if mem package is initialized. */ + /* Test this if you have other packages */ + /* that depend on mem being initialized */ + +/********************* PUBLIC FUNCTIONS *************************/ + +/*********************************** + * Set behavior when mem runs out of memory. + * Input: + * flag = MEM_ABORTMSG: Abort the program with the message + * 'Fatal error: out of memory' sent + * to stdout. This is the default behavior. + * MEM_ABORT: Abort the program with no message. + * MEM_RETNULL: Return NULL back to caller. + * MEM_CALLFP: Call application-specified function. + * fp must be supplied. + * fp Optional function pointer. Supplied if + * (flag == MEM_CALLFP). This function returns + * MEM_XXXXX, indicating what mem should do next. + * The function could do things like swap + * data out to disk to free up more memory. + * fp could also return: + * MEM_RETRY: Try again to allocate the space. Be + * careful not to go into an infinite loop. + */ + +#if __cplusplus +enum MEM_E { MEM_ABORTMSG, MEM_ABORT, MEM_RETNULL, MEM_CALLFP, MEM_RETRY }; +void mem_setexception P((enum MEM_E, int (*)())); +#else +#define MEM_ABORTMSG 0 +#define MEM_ABORT 1 +#define MEM_RETNULL 2 +#define MEM_CALLFP 3 +#define MEM_RETRY 4 +void mem_setexception P((int, int(*)())); +#endif + + +/**************************** + * Allocate space for string, copy string into it, and + * return pointer to the new string. + * This routine doesn't really belong here, but it is used so often + * that I gave up and put it here. + * Use: + * char *mem_strdup(const char *s); + * Returns: + * pointer to copied string if succussful. + * else returns NULL (if MEM_RETNULL) + */ + +char *mem_strdup P((const char *)); + +/************************** + * Function so we can have a pointer to function mem_free(). + * This is needed since mem_free is sometimes defined as a macro, + * and then the preprocessor screws up. + * The pointer to mem_free() is used frequently with the list package. + * Use: + * void mem_freefp(void *p); + */ + +/*************************** + * Check for errors. This routine does a consistency check on the + * storage allocator, looking for corrupted data. It should be called + * when the application has CPU cycles to burn. + * Use: + * void mem_check(void); + */ + +void mem_check P((void )); + +/*************************** + * Check ptr to see if it is in the range of allocated data. + * Cause assertion failure if it isn't. + */ + +void mem_checkptr P((void *ptr)); + +/*************************** + * Allocate and return a pointer to numbytes of storage. + * Use: + * void *mem_malloc(unsigned numbytes); + * void *mem_calloc(unsigned numbytes); allocated memory is cleared + * Input: + * numbytes Number of bytes to allocate + * Returns: + * if (numbytes > 0) + * pointer to allocated data, NULL if out of memory + * else + * return NULL + */ + +void *mem_malloc P((unsigned)); +void *mem_calloc P((unsigned)); + +/***************************** + * Reallocate memory. + * Use: + * void *mem_realloc(void *ptr,unsigned numbytes); + */ + +void *mem_realloc P((void *,unsigned)); + +/***************************** + * Free memory allocated by mem_malloc(), mem_calloc() or mem_realloc(). + * Use: + * void mem_free(void *ptr); + */ + +void mem_free P((void *)); + +/*************************** + * Initialize memory handler. + * Use: + * void mem_init(void); + * Output: + * mem_inited = 1 + */ + +void mem_init P((void )); + +/*************************** + * Terminate memory handler. Useful for checking for errors. + * Use: + * void mem_term(void); + * Output: + * mem_inited = 0 + */ + +void mem_term P((void )); + +/* The following stuff forms the implementation rather than the + * definition, so ignore it. + */ + +#if MEM_DEBUG /* if creating debug version */ +#define mem_strdup(p) mem_strdup_debug((p),__FILE__,__LINE__) +#define mem_malloc(u) mem_malloc_debug((u),__FILE__,__LINE__) +#define mem_calloc(u) mem_calloc_debug((u),__FILE__,__LINE__) +#define mem_realloc(p,u) mem_realloc_debug((p),(u),__FILE__,__LINE__) +#define mem_free(p) mem_free_debug((p),__FILE__,__LINE__) + +char *mem_strdup_debug P((const char *,char *,int)); +void *mem_calloc_debug P((unsigned,char *,int)); +void *mem_malloc_debug P((unsigned,char *,int)); +void *mem_realloc_debug P((void *,unsigned,char *,int)); +void mem_free_debug P((void *,char *,int)); +void mem_freefp P((void *)); + +void mem_setnewfileline P((void *,char *,int)); + +#else + +#define mem_freefp mem_free +#define mem_check() +#define mem_checkptr(p) + +#endif /* MEM_DEBUG */ + +#endif /* MEM_H */ diff --git a/reference/C/CONTRIB/SNIP/mem.txt b/reference/C/CONTRIB/SNIP/mem.txt new file mode 100755 index 0000000..7b6d0b8 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/mem.txt @@ -0,0 +1,215 @@ + Walter Bright's MEM Package + --------------------------- + + +PREFACE: +-------- + +The files, MEM.H and MEM.C which constitute the MEM package were originally +published in the March-April 1990 edition of Micro Cornucopia magazine, now +sadly out of print. The files as they appear in SNIPPETS have been edited +somewhat to remove compiler dependencies and correct minor discrepancies. + +For those who don't already know, Walter Bright is the author of Datalight +Optimum-C, the original optimizing C compiler for PC's. Through a succession +of sales and acquisitions plus continual improvement by Walter,, his compiler +became Zortech C++ and is now sold as Symantec C++. As such, it is the only +major PC compiler which can claim single authorship. It also compiles faster +than most other compilers and is still a market leader in its optimization +technology. + +Like many other library and ancillary functions unique to Walter's compilers, +the MEM package was originally something he wrote for his own use. As noted +above, he published it only once but it has been included as an unheralded +"freebie" in Walter's compilers for the past several years. Walter was kind +enough to grant permission for its inclusion in SNIPPETS beginning with the +April, '94 release. + + +WHAT IS MEM?: +------------- + +MEM is a set of functions used for debugging C pointers and memory allocation +problems. Quoting Walter, "Symptoms of pointer bugs include: hung machines, +scrambled disks, failures that occur once-in-10,000 iterations, irreprodu- +cible results, and male pattern baldness." After writing MEM for use in +developing his own compiler and tools, he reported that its use reduced +pointer bugs by as much as 75%. MEM is simple to add to existing programs +and adds little or no overhead. + + +USING MEM: +---------- + +Included in the MEM package is TOOLKIT.H, which isolates compiler and +environmental dependencies. It should work as-is for most PC compilers and +the Microsoft compiler for SCO Unix. Other environments may be customized by +writing your own HOST.H file, using the existing definitions in TOOLKIT.H as +examples and modifying the values to match your system. Using these +techniques, the MEM package has been used successfully on Amigas, Macs, +VAXes, and many other non-DOS systems. + +The MEM functions exactly parallel the standard library (plus 1 non-standard) +memory allocation functions. To implement MEM in your program, simply do a +global search-and-replace of the following functions: + + malloc() -> mem_malloc() + calloc() -> mem_calloc() + realloc() -> mem_realloc() + free() -> mem_free() + strdup() -> mem_strdup() + +At the beginning of main(), add the following lines: + + mem_init(); + atexit(mem_term); + +In the header section of each of your C files, add... + +#include "mem.h" + +...to every .C file which calls any of the above functions. + +The final step is to compile and link MEM.C into all programs using the MEM +package. It really is a pretty simple procedure! + +MEM has 2 modes of operation, debugging and non-debugging. Use debugging +mode during program development and then turn debugging off for final +production code. Control of debugging is by defining the MEM_DEBUG macro. +If the macro is defined, debugging is on; if undefined, debugging is off. +The default is non-debugging, in which case the MEM functions become trivial +wrappers for the standard functions, incurring virtually no overhead. + + +WHAT MEM DOES: +-------------- + +1. ISO/ANSI verification: + +When Walter wrote MEM, compiler compliance with ANSI standards was still +quite low. MEM verifies ISO/ANSI compliance for situations such as passing +NULL or size 0 to allocation/reallocation functions. + +2. Logging of all allocations and frees: + +All MEM's functions pass the __FILE__ and __LINE__ arguments. During alloca- +tion, MEM makes an entry into a linked list and stores the file and line +information in the list for whichever allocation or free function is called. + +This linked list is the backbone of MEM. When MEM detects a bug, it tells +you where to look in which file to begin tracking the problem. + +3. Verification of frees: + +Since MEM knows about all allocations, when a pointer is freed, MEM can +verify that the pointer was allocated originally. Additionally, MEM will +only allow a pointer to be freed once. + +Freed data is overwritten with a non-zero known value, flushing such problems +as continuing to reference data after it's been freed. The value written +over the data is selected to maximize the probability of a segment fault or +assertion failure if your application references it after it's been freed. + +MEM obviously can't directly detect "if" instances such as... + + mem_free(p); + if (p) ... + +...but by guaranteeing that `p' points to garbage after being freed, code +like this will hopefully never work and will thus be easier to find. + +4. Detection of pointer over- and under-run: + +Pointer overrun occurs when a program stores data past the end of a buffer, +e.g. + + p = malloc(strlen(s)); /* No space for terminating NUL */ + strcpy(p,s); /* Terminating NUL clobber memory */ + +Pointer underrun occurs when a program stores data before the beginning of a +buffer. This error occurs less often than overruns, but MEM detects it +anyway. MEM does this by allocating a little extra at each end of every +buffer, which is filled with a known value, called a sentinel. MEM detects +overruns and underruns by verifying the sentinel value when the buffer is +freed. + +5. Dependence on values in buffer obtained from malloc(): + +When obtaining a buffer from malloc(), a program may develop erroneous and +creeping dependencies on whatever random (and sometimes repeatable) values +the buffer may contain. The mem_malloc() function prevents this by always +setting the data in a buffer to a known non-zero value before returning its +pointer. This also prevents another common error when running under MS-DOS +which doesn't clear unused memory when loading a program. These bugs are +particularly nasty to find since correct program operation may depend on what +was last run! + +6. Realloc problems: + +Common problems when using realloc() are: 1) depending on realloc() *not* +shifting the location of the buffer in memory, and 2) depending on finding +certain values in the uninitialized region of the realloc'ed buffer. + +MEM flushes these out by *always* moving the buffer and stomping on values +past the initialized area. + +7. Memory leak detection: + +Memory "leaks" are areas that are allocated but never freed. This can become +a major problem in programs that must run for long periods without interrup- +tion (e.g. BBS's). If there are leaks, eventually the program will run out +of memory and fail. + +Another form of memory leak occurs when a piece of allocated memory should +have been added to some central data structure, but wasn't. + +MEM find memory leaks by keeping track of all allocations and frees. When +mem_term() is called, a list of all unfreed allocations is printed along with +the files and line numbers where the allocations occurred. + +8. Pointer checking: + +Sometimes it's useful to be able to verify that a pointer is actually +pointing into free store. MEM provides a function... + + mem_checkptr(void *p); + +...to do this. + +9. Consistency checking: + +Occasionally, even MEM's internal data structures get clobbered by a wild +pointer. When this happens, you can track it down by sprinkling your code +temporarily with calls to mem_check(), which performs a consistency check on +the free store. + +10. Out of memory handling: + +MEM can be set using mem_setexception() (see MEM.H) to handle out-of-memory +conditions in any one of several predefined ways: + + 1. Present an "Out of memory" message and terminate the program. + 2. Abort the program with no message. + 3. Mimic ISO/ANSI and return NULL. + 4. Call a user-specified function, perhaps involving virtual memory + or some other "emergency reserve". + 5. Retry (be careful to avoid infinite loops!) + +11. Companion techniques: + +Since MEM presets allocated and stomps on freed memory, this facilitates +adding your own code to add tags to your data structures when debugging. If +the structures are invalid, you'll know it because MEM will have clobbered +your verification tags. + + +SUMMARY: +-------- + +Since it is, in the final analysis, a software solution, MEM is fallible. As +the saying goes, "Nothing is foolproof because fools are so ingenious." +Walter himself readily acknowledges that there are circumstances where your +code can do sufficient damage to MEM's internal data structures to render it +useless. The good news is such circumstances are few and far between. For +most memory debugging, MEM is a highly reliable and valuable addition to your +C programming toolchest. diff --git a/reference/C/CONTRIB/SNIP/memavail.c b/reference/C/CONTRIB/SNIP/memavail.c new file mode 100755 index 0000000..67400d9 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/memavail.c @@ -0,0 +1,32 @@ +/* +** MEMAVAIL.C - Report available DOS memory +** +** public domain by Thor Johnson +*/ + +#include + +long memavail(void) +{ + union REGS regs; + + /* Request impossibly large number of 16-byte paragraphs from DOS */ + + regs.h.ah = 0x48; + regs.x.bx = 0xFFFF; + + int86(0x21,®s,®s); + + return((long)regs.x.bx * 16L); +} + +#ifdef TEST + +#include + +main() +{ + printf("Available DOS memory = %ld bytes\n", memavail()); +} + +#endif /* TEST */ diff --git a/reference/C/CONTRIB/SNIP/memrev.c b/reference/C/CONTRIB/SNIP/memrev.c new file mode 100755 index 0000000..e94d435 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/memrev.c @@ -0,0 +1,52 @@ +/* +** Public domain demo by Ray Gardner, 7 dec 88 +** +** Here's an old programming trick that (I bet) will be new to at least a +** few of you out there, even some "old hands". I don't remember where I +** saw this; it might have been Jon Bentley's "Programming Pearls" column in +** Communications of the ACM. +** +** Have you ever wanted to exchange two adjacent areas of storage which +** might be of two different lengths? There are some tricky and complicated +** "efficient" methods to do this without using a lot of extra temporary +** storage. But there is also an old and simple way: Assume that the buffer +** looks like this: +** +** |...... head .......|.................. tail .................| +** +** You reverse the head, reverse the tail, then reverse the entire buffer. +** That's all there is to it. It will leave you with: +** +** |.................. tail .................|...... head .......| +** +** Here's code: +*/ + +#include + +/* +** reverse "count" bytes starting at "buf" +*/ + +void memrev(char *buf, size_t count) +{ + char *r; + + for (r = buf + count - 1; buf < r; buf++, r--) + { + *buf ^= *r; + *r ^= *buf; + *buf ^= *r; + } +} + +/* +** swap "head" bytes with "tail" bytes at "buf" +*/ + +void aswap(char *buf, size_t head, size_t tail) +{ + memrev(buf, head); + memrev(buf + head, tail); + memrev(buf, head + tail); +} diff --git a/reference/C/CONTRIB/SNIP/missing.txt b/reference/C/CONTRIB/SNIP/missing.txt new file mode 100755 index 0000000..958b366 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/missing.txt @@ -0,0 +1,21 @@ + M.I.A. Files + ------------ + + +Several folks have asked about the files that inevitably disappear from one +SNIPPETS release to the next. Some have gone so far as to suggest I include +a brief rationale within SNIPPETS.NDX why each deleted entry (marked with a +'-' in the first column) was dropped. This would be impractical since +SNIPPETS.NDX is more than a simple index - it also acts as the control file +for SNIPDIFF. A such it is maintained by a separate program and its entries +read in order when producing SNIPDIFF. More importantly, its file +verification tag is computed during the automatic maintenance cycle. + +In other words, it's more work than I want to tackle right now, OK? + +This file is therefore a separate list of all the files deleted from SNIPPETS +since the last release along with the reason they were removed: + +Dow.H : Bug in early 21st century - replaced by function in SCALDATE.C +Dd_Struc.C : Renamed DD_STRUCT.H +Figets.C : Buggy, not yet fixed diff --git a/reference/C/CONTRIB/SNIP/mkdirs.c b/reference/C/CONTRIB/SNIP/mkdirs.c new file mode 100755 index 0000000..b9228e4 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/mkdirs.c @@ -0,0 +1,52 @@ +/* +** MKDIRS.C - Function to build multi-level directories in a single call +** +** Original Copyright 1993 by Bob Stout as part of +** the MicroFirm Function Library (MFL) +** +** This subset version is hereby donated to the public domain. +*/ + +#include +#include +#include +#ifdef __TURBOC__ + #include +#else + #include +#endif + +int mkdirs(char *path) +{ + int retval; + + while (0 != (retval = mkdir(path))) + { + char subpath[FILENAME_MAX] = "", *delim; + + if (NULL == (delim = strrchr(path, '\\'))) + return retval; + strncat(subpath, path, delim - path); /* Appends NUL */ + mkdirs(subpath); + } + return retval; +} + +#ifdef TEST + +main(int argc, char *argv[]) +{ + if (2 > argc) + { + puts("Usage: MKDIRS pathname [...pathname]"); + return -1; + } + while (--argc) + { + ++argv; + printf("mkdirs(%s) returned %d\n", *argv, mkdirs(*argv)); + } + return 0; +} + +#endif /* TEST */ diff --git a/reference/C/CONTRIB/SNIP/mktone.c b/reference/C/CONTRIB/SNIP/mktone.c new file mode 100755 index 0000000..427bc5a --- /dev/null +++ b/reference/C/CONTRIB/SNIP/mktone.c @@ -0,0 +1,52 @@ +/* +** MKTONE.C +** +** Original Copyright 1988-1991 by Bob Stout as part of +** the MicroFirm Function Library (MFL) +** +** This subset version is functionally identical to the +** version originally published by the author in Tech Specialist +** magazine and is hereby donated to the public domain. +*/ + +#include "uclock.h" +#include "sound.h" + +static int usec_timeout(uclock_t start, uclock_t finish, uclock_t usecs) +{ + if (usecs >= (finish - start)) + return 0; + else return 1; +} + +void dosound(int freq) +{ + unsigned i; + + outp(C8253, SETIMER); + i = (unsigned)freq%256; + outp(F8253, i); + i = (unsigned)freq/256; + outp(F8253, i); +} + +void mktone(int freq, int update, unsigned delay) +{ + uclock_t start; + + if (0 == freq) + { + soundoff(); + return; + } + dosound(freq); + if (update != UPDATE) + soundon(); + if (delay == 0) + return; + start = usec_clock(); + while (!usec_timeout(start, usec_clock(), 1000L * (long)delay)) + ; + if (update == TOGGLE) + soundoff(); +} diff --git a/reference/C/CONTRIB/SNIP/moon_age.c b/reference/C/CONTRIB/SNIP/moon_age.c new file mode 100755 index 0000000..e979498 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/moon_age.c @@ -0,0 +1,66 @@ +/* PD by Michelangelo Jones, 1:1/124. */ + +/* +** Returns 0 for new moon, 15 for full moon, +** 29 for the day before new, and so forth. +*/ + +/* +** This routine sometimes gets "off" by a few days, +** but is self-correcting. +*/ + +int moon_age(int month, int day, int year) +{ + static short int ages[] = + {18, 0, 11, 22, 3, 14, 25, 6, 17, + 28, 9, 20, 1, 12, 23, 4, 15, 26, 7}; + static short int offsets[] = + {-1, 1, 0, 1, 2, 3, 4, 5, 7, 7, 9, 9}; + + if (day == 31) + day = 1; + return ((ages[(year + 1) % 19] + ((day + offsets[month-1]) % 30) + + (year < 1900)) % 30); +} + +#ifdef TEST + +#include +#include + +static char *description[] = { + "new", /* totally dark */ + "waxing crescent", /* increasing to full & quarter light */ + "in its first quarter", /* increasing to full & half light */ + "waxing gibbous", /* increasing to full & > than half */ + "full", /* fully lighted */ + "waning gibbous", /* decreasing from full & > than half */ + "in its last quarter", /* decreasing from full & half light */ + "waning crescent" /* decreasing from full & quarter light */ + }; + +static char *months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; + +int main(int argc, char *argv[]) +{ + int month, day, year, phase; + + if (4 > argc) + { + puts("Usage: MOON_AGE month day year"); + return EXIT_FAILURE; + } + month = atoi(argv[1]); + day = atoi(argv[2]); + year = atoi(argv[3]); + if (100 > year) + year += 1900; + printf("moon_age(%d, %d, %d) returned %d\n", month, day, year, + phase = moon_age(month, day, year)); + printf("Moon phase on %d %s %d is %s\n", day, months[month - 1], year, + description[(int)((phase + 2) * 16L / 59L)]); +} + +#endif /* TEST */ diff --git a/reference/C/CONTRIB/SNIP/morse.c b/reference/C/CONTRIB/SNIP/morse.c new file mode 100755 index 0000000..a280343 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/morse.c @@ -0,0 +1,238 @@ +/* +** <<< Morse Code Functions >>> +** +** Written by Michael M. Dodd, N4CF, and placed in the public domain. +** +** The morse() function transmits a string in Morse code on the IBM PC's +** speaker. The speed is set by a program constant (UNIT_TIME). +** +** There are several other functions in this file, all used by morse(), +** and defined ahead of morse() for convenience. +** +** The main() function at the end of the file is a test program to send +** the command-line argument string in morse code. Enclose multiple +** words in quotes. Example: morse "hello, world" +** +** These functions have been compiled and tested in the Small and Large +** memory models using Microsoft C 6.00a. +** +** Modified for ZTC++, TC++, & BC++ by Bob Stout +*/ + +#include +#include +#include +#include + +/* +** These functions turn on and off the CW tone on the PC's speaker. The +** frequency is specified by the freq argument. +** IMPORTANT! These functions are highly IBM PC-specific! +*/ + +#define CLK_FREQ (1193180L) +#define PIO (0x61) +#define CTC_CMD (0x43) +#define CTC_DATA (0x42) +#define SETUP (0xB6) +#define TONE_ON (0x03) +#define TONE_OFF (0xFC) + +void note_on (int freq) /* Turn on the tone. */ +{ + int divisor ; + int pio_word ; + + divisor = (int)(CLK_FREQ / (long)(freq)) ; + outp (CTC_CMD, SETUP) ; + outp (CTC_DATA, divisor & 0xFF) ; + outp (CTC_DATA, divisor >> 8) ; + pio_word = inp (PIO) ; + outp (PIO, pio_word | TONE_ON) ; +} + +void note_off (void) /* Turn off the tone. */ +{ + int pio_word ; + + pio_word = inp (PIO) ; + outp (PIO, pio_word & TONE_OFF) ; +} + +/* +** These functions implement a timing-loop delay. Because the PC's +** internal clock is too coarse for accurate CW timing, the pause() +** function uses a simple software loop to produce a delay. +** +** To minimize the effects of CPU clock speed, the calib() function +** returns a number which represents a rough index of the clock speed +** with relation to the standard IBM PC (this is very approximate). +** +** Calibration is performed only once, when the static fudge_factor is +** zero. Thereafter, the contents of fudge_factor are used to form a +** delay value. +** +** IMPORTANT! These functions are highly IBM PC-specific! +*/ + +unsigned int calib (void) +{ + unsigned int far *timerLow = (unsigned int far *)(0x046c) ; + unsigned int lastTime ; + unsigned int iter ; + + for (lastTime = *timerLow; lastTime == *timerLow;) + ; + + for (iter = 0, lastTime = *timerLow; lastTime == *timerLow; iter++) + ; +#if defined(__ZTC__) + return ((unsigned int)((125L * ((long)(iter)) + 50L) / 2300L)) ; +#elif defined(__TURBOC__) + return ((unsigned int)((77L * ((long)(iter)) + 50L) / 2300L)) ; +#else /* assume MSC */ + return ((unsigned int)((100L * ((long)(iter)) + 50L) / 2300L)) ; +#endif +} + +void pause (unsigned int amount) +{ + static unsigned int fudge_factor = 0 ; + unsigned long ul ; + + if (fudge_factor == 0) /* Calibrate the speed. */ + fudge_factor = calib () ; + + ul = (unsigned long)(amount) * (long)(fudge_factor) ; + while (ul--) /* Delay. */ + ; +} + +/* +** These functions transmit a dot, a dash, a letter space, and a +** word space. +** +** Note that a single unit space is automatically transmitted after +** each dot or dash, so the ltr_space() function produces only a +** two-unit pause. +** +** Also, the word_space() function produces only a four-unit pause +** because the three-unit letter space has already occurred following +** the previous letter. +*/ + +#define SPACE_MASK (1 << 15) +#define BIT_MASK (0xfe) +#define UNIT_TIME (18) +#define FREQUENCY (1500) + +void send_dot (void) /* Send a dot and a space. */ +{ + note_on (FREQUENCY) ; + pause (UNIT_TIME) ; + note_off () ; + pause (UNIT_TIME) ; +} + +void send_dash (void) /* Send a dash and a space. */ +{ + note_on (FREQUENCY) ; + pause (UNIT_TIME * 3) ; + note_off () ; + pause (UNIT_TIME) ; +} + +void ltr_space (void) /* Produce a letter space. */ +{ + pause (UNIT_TIME * 2) ; +} + +void word_space (void) /* Produce a word space. */ +{ + pause (UNIT_TIME * 4) ; +} + + +/* +** MORSE () - Transmit a string in Morse code +** +** This function transmits the string pointed to by the cp argument in +** Morse code on the PC's speaker. The speed is set by the UNIT_TIME +** constant. +** +** A static table translates from ASCII to Morse code. Each entry is +** an unsigned integer, where a zero represents a dot and a one +** represents a dash. No more than 14 bits may be used. Setting bit +** 15 produces a word space, regardless of any other pattern. +** +** The Morse code pattern is taken from bit 0, and is shifted right +** each time an element is sent. A special "marker bit" follows the +** complete Morse pattern. This marker bit is tested before +** transmitting each bit; if there are no 1's in bits 1..15, the +** complete character has been sent. +** +** For example, an "L" would be 0000000000010010, with bit zero +** containing the first dot, bit one the dash, etc. The marker +** bit is in bit 4. +*/ + +void morse (char *cp) +{ /*--- MORSE CODE FUNCTION ---*/ + + unsigned int c ; + static unsigned int codes [64] = { + SPACE_MASK, /* Entry 0 = space (0x20) */ + 0, 0, 0, 0, 0, 0, 0, 0, /* ! " # $ % & " ( */ + 0, 0, 0, 115, 49, 106, 41, /* ) * + , - . / */ + 63, 62, 60, 56, 48, 32, 33, 35, /* 0 1 2 3 4 5 6 7 */ + 39, 47, 0, 0, 0, 0, 0, 76, /* 8 9 : ; < = > ? */ + 0, 6, 17, 21, 9, 2, 20, 11, /* @ A B C D E F G */ + 16, 4, 30, 13, 18, 7, 5, 15, /* H I J K L M N O */ + 22, 27, 10, 8, 3, 12, 24, 14, /* P Q R S T U V W */ + 25, 29, 19 /* X Y Z */ + } ; + + pause (0) ; /* Calibrate pause() function. */ + + while ((c = *cp++) != '\0') + { /*--- TRANSMIT COMPLETE STRING ---*/ + + c = toupper (c) ; /* No lower-case Morse characters. */ + c -= ' ' ; /* Adjust for zero-based table. */ + + if (c < 0 || c > 58) /* If out of range, ignore it. */ + continue ; + + c = codes[c] ; /* Look up Morse pattern from table. */ + + if (c & SPACE_MASK) /* If the space bit is set.. */ + { /* ..send a word space and go on. */ + word_space () ; + continue ; + } + + while (c & BIT_MASK) /* Transmit one character. */ + { /*--- TRANSMIT EACH BIT ---*/ + if (c & 1) + send_dash () ; + else send_dot () ; + + c >>= 1 ; + } /*--- TRANSMIT EACH BIT ---*/ + + ltr_space () ; /* Send a space following character. */ + + } /*--- TRANSMIT COMPLETE STRING ---*/ + +} /*--- MORSE CODE FUNCTION ---*/ + + +/* +** This is the test program, which transmits argv[1] in Morse code. +*/ + +void main (int argc, char *argv[]) +{ + if (argc > 1) + morse (argv[1]) ; +} diff --git a/reference/C/CONTRIB/SNIP/mouse.c b/reference/C/CONTRIB/SNIP/mouse.c new file mode 100755 index 0000000..71f165b --- /dev/null +++ b/reference/C/CONTRIB/SNIP/mouse.c @@ -0,0 +1,352 @@ +/* +** A series of routines to provide access to MicroSoft (and compatible) +** mice. Consult your mouse documentation for detailed information regarding +** each mouse driver function. +** +** by Bob Jarvis w/ modifications by Bob Stout +*/ + +#include +#include "mouse.h" + +int mouse_present = 0; /* globally visible */ + +/* +** Uses driver function 0 to initialize the mouse software to its default +** settings. If no mouse is present it returns 0. If a mouse is present, it +** returns -1, and places the value of the mouse type (2 = MicroSoft, +** 3 = Mouse Systems, other values are possible) in *mousetype. Also +** initializes the global variable mouse_present (0 = no mouse, !0 = mouse +** is available). +*/ + +int ms_reset(int *mousetype) +{ + union REGS workregs; + struct SREGS sregs; + + /* check the vector */ + + segread (&sregs); + workregs.h.ah = 0x35; /* DOS get vector */ + workregs.h.al = 0x33; /* mouse vector */ + intdosx(0x21, &workregs, &workregs, &sregs); + + /* ES:BX now contains the pointer to the interrupt handler */ + + if (sregs.es == 0 && inregs.x.bx == 0) + return mouse_present = 0; + + workregs.x.ax = 0; + int86(MSMOUSE,&workregs,&workregs); + *mousetype = workregs.x.bx; + mouse_present = workregs.x.ax; + return(mouse_present); +} + +/* +** Makes the mouse cursor visible. +*/ + +void ms_show_cursor(void) +{ + union REGS workregs; + + workregs.x.ax = 1; + int86(MSMOUSE,&workregs,&workregs); +} + +/* +** Hides the mouse cursor. Should be called before changing any portion of +** the screen under the mouse cursor. +*/ + +void ms_hide_cursor(void) +{ + union REGS workregs; + + workregs.x.ax = 2; + int86(MSMOUSE,&workregs,&workregs); +} + +/* +** Obtains information about the mouse position and button status. +** Places the current horizontal and vertical positions in *horizpos and +** *vertpos, respectively. Returns the mouse button status, which is +** mapped at the bit level as follows: +** Bit 0 - left button \ +** Bit 1 - right button >-- 0 = button up, 1 = button down +** Bit 2 - middle button / +*/ + +int ms_get_mouse_pos(int *horizpos, int *vertpos) /* Returns button status */ +{ + union REGS workregs; + + workregs.x.ax = 3; + int86(MSMOUSE,&workregs,&workregs); + *horizpos = workregs.x.cx; + *vertpos = workregs.x.dx; + return(workregs.x.bx); +} + +/* +** Moves the mouse cursor to a new position. +*/ + +void ms_set_mouse_pos(int horizpos, int vertpos) +{ + union REGS workregs; + + workregs.x.ax = 4; + workregs.x.cx = horizpos; + workregs.x.dx = vertpos; + int86(MSMOUSE,&workregs,&workregs); +} + +/* +** Obtains information about the last time the specified button +** (0 = left, 1 = right, 2 = middle) was pressed. Returns the current +** button status (same format as return from ms_get_mouse_pos() above). +*/ + +int ms_button_press_status(int button, + int *press_count, + int *column, + int *row) +{ + union REGS workregs; + + workregs.x.ax = 5; + workregs.x.bx = button; + int86(MSMOUSE,&workregs,&workregs); + *press_count = workregs.x.bx; + *column = workregs.x.cx; + *row = workregs.x.dx; + return(workregs.x.ax); +} + +/* +** Similar to above but obtains information about the last release of the +** specified button. +*/ + +int ms_button_release_status(int button, + int *release_count, + int *column, + int *row) +{ + union REGS workregs; + + workregs.x.ax = 6; + workregs.x.bx = button; + int86(MSMOUSE,&workregs,&workregs); + *release_count = workregs.x.bx; + *column = workregs.x.cx; + *row = workregs.x.dx; + return(workregs.x.ax); +} + +/* +** Forces the mouse cursor to remain within the range specified. +*/ + +void ms_restrict_horiz(int min, int max) +{ + union REGS workregs; + + workregs.x.ax = 7; + workregs.x.cx = min; + workregs.x.dx = max; + int86(MSMOUSE,&workregs,&workregs); +} + +/* +** Forces the mouse cursor to remain within the range specified. +*/ + +void ms_restrict_vert(int min, int max) +{ + union REGS workregs; + + workregs.x.ax = 8; + workregs.x.cx = min; + workregs.x.dx = max; + int86(MSMOUSE,&workregs,&workregs); +} + +void ms_define_window(int left, int top, int right, int bottom) +{ + ms_restrict_horiz(left,right); + ms_restrict_vert(top,bottom); +} + +/* +** Allows the user to set the graphics cursor to a new shape. Check your +** mouse reference manual for full information about the use of this function. +*/ + +void ms_set_graphics_cursor(int horiz_hotspot, + int vert_hotspot, + unsigned seg_shape_tables, + unsigned offset_shape_tables) +{ + union REGS workregs; + struct SREGS segregs; + + workregs.x.ax = 9; + workregs.x.bx = horiz_hotspot; + workregs.x.cx = vert_hotspot; + workregs.x.dx = offset_shape_tables; + segregs.es = seg_shape_tables; + int86x(MSMOUSE,&workregs,&workregs,&segregs); +} + +/* +** Selects either the software or hardware cursor and sets the start and stop +** scan lines (for the hardware cursor) or the screen and cursor masks (for +** the software cursor). Consult your mouse reference for more information. +*/ + +void ms_set_text_cursor(int type, int screen_mask, int cursor_mask) +{ + union REGS workregs; + + workregs.x.ax = 10; + workregs.x.bx = type; + workregs.x.cx = screen_mask; + workregs.x.dx = cursor_mask; + int86(MSMOUSE,&workregs,&workregs); +} + +/* +** Obtains the horizontal and vertical raw motion counts since the last +** request. +*/ + +void ms_read_motion_counters(int *horiz, int *vert) +{ + union REGS workregs; + + workregs.x.ax = 11; + int86(MSMOUSE,&workregs,&workregs); + *horiz = workregs.x.cx; + *vert = workregs.x.dx; +} + +/* +** Sets up a subroutine to be called when a given event occurs. +** NOTE: Use with extreme care. The function whose address is provided MUST +** terminate with a far return (i.e. must be compiled using large model). +** Also, no DOS or BIOS services may be used, as the user-defined function +** is (in effect) an extension to an interrupt service routine. +*/ + +void ms_set_event_subroutine(int mask, + unsigned seg_routine, + unsigned offset_routine) +{ + union REGS workregs; + struct SREGS segregs; + + workregs.x.ax = 12; + workregs.x.cx = mask; + workregs.x.dx = offset_routine; + segregs.es = seg_routine; + int86x(MSMOUSE,&workregs,&workregs,&segregs); +} + +/* +** Turns light pen emulation mode on. +*/ + +void ms_light_pen_on(void) +{ + union REGS workregs; + + workregs.x.ax = 13; + int86(MSMOUSE,&workregs,&workregs); +} + +/* +** turns light pen emulation mode off. +*/ + +void ms_light_pen_off(void) +{ + union REGS workregs; + + workregs.x.ax = 14; + int86(MSMOUSE,&workregs,&workregs); +} + +/* +** Sets the sensitivity of the mouse. Defaults are 8 and 16 for horizontal +** and vertical sensitivity (respectively). +*/ + +void ms_set_sensitivity(int horiz, int vert) +{ + union REGS workregs; + + workregs.x.ax = 15; + workregs.x.cx = horiz; + workregs.x.dx = vert; + int86(MSMOUSE,&workregs,&workregs); +} + +/* +** Sets up a region of the screen inside of which the mouse cursor will +** automatically be 'hidden'. +*/ + +void ms_protect_area(int left, int top, int right, int bottom) +{ + union REGS workregs; + + workregs.x.ax = 16; + workregs.x.cx = left; + workregs.x.dx = top; + workregs.x.si = right; + workregs.x.di = bottom; + int86(MSMOUSE,&workregs,&workregs); +} + +/* +* Similar to ms_set_graphics_cursor() but allows a larger cursor. Consult +** your mouse documentation for information on how to use this function. +*/ + +int ms_set_large_graphics_cursor(int width, + int height, + int horiz_hotspot, + int vert_hotspot, + unsigned seg_shape_tables, + unsigned offset_shape_tables) +{ + union REGS workregs; + struct SREGS segregs; + + workregs.x.ax = 18; + workregs.x.bx = (width << 8) + horiz_hotspot; + workregs.x.cx = (height << 8) + vert_hotspot; + workregs.x.dx = offset_shape_tables; + segregs.es = seg_shape_tables; + int86x(MSMOUSE,&workregs,&workregs,&segregs); + if(workregs.x.ax == -1) + return(workregs.x.ax); /* Return -1 if function 18 supported */ + else return(0); /* else return 0 */ +} + +/* +** Sets the threshold value for doubling cursor motion. Default value is 64. +*/ + +void ms_set_doublespeed_threshold(int speed) +{ + union REGS workregs; + + workregs.x.ax = 19; + workregs.x.dx = speed; + int86(MSMOUSE,&workregs,&workregs); +} diff --git a/reference/C/CONTRIB/SNIP/mouse.h b/reference/C/CONTRIB/SNIP/mouse.h new file mode 100755 index 0000000..c433838 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/mouse.h @@ -0,0 +1,38 @@ +/* module: mouse.h + * programmer: Ray L. McVay + * started: 26oct86 + * updated: 26oct86 + * + * Some handy mouse interface functions. + */ + +#ifdef __TURBOC__ + #define FAR far +#else + #define FAR _far +#endif + +#define MSMOUSE 0x33 + +extern int mouse_present; + +int ms_reset(int *); +void ms_show_cursor(void); +void ms_hide_cursor(void); +int ms_get_mouse_pos(int *, int *); +void ms_set_mouse_pos(int, int); +int ms_button_press_status(int, int *, int *, int *); +int ms_button_release_status(int, int *, int *, int *); +void ms_restrict_horiz(int, int); +void ms_restrict_horiz(int, int); +void ms_define_window(int, int, int, int); +void ms_set_graphics_cursor(int, int, unsigned, unsigned); +void ms_set_text_cursor(int, int, int); +void ms_read_motion_counters(int *, int *); +void ms_set_event_subroutine(int, unsigned, unsigned); +void ms_light_pen_on(void); +void ms_light_pen_off(void); +void ms_set_sensitivity(int, int); +void ms_protect_area(int, int, int, int); +int ms_set_large_graphics_cursor(int, int, int, int, unsigned, unsigned); +void ms_set_doublespeed_threshold(int); diff --git a/reference/C/CONTRIB/SNIP/msb2ieee.c b/reference/C/CONTRIB/SNIP/msb2ieee.c new file mode 100755 index 0000000..74265c0 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/msb2ieee.c @@ -0,0 +1,59 @@ +/*** MSBIN conversion routines ***/ +/*** public domain by Jeffery Foy ***/ + +union Converter { + unsigned char uc[10]; + unsigned int ui[5]; + unsigned long ul[2]; + float f[2]; + double d[1]; +}; + +/* MSBINToIEEE - Converts an MSBIN floating point number */ +/* to IEEE floating point format */ +/* */ +/* Input: f - floating point number in MSBIN format */ +/* Output: Same number in IEEE format */ + +float MSBINToIEEE(float f) +{ + union Converter t; + int sign, exp; /* sign and exponent */ + + t.f[0] = f; + + /* extract the sign & move exponent bias from 0x81 to 0x7f */ + + sign = t.uc[2] / 0x80; + exp = (t.uc[3] - 0x81 + 0x7f) & 0xff; + + /* reassemble them in IEEE 4 byte real number format */ + + t.ui[1] = (t.ui[1] & 0x7f) | (exp << 7) | (sign << 15); + return t.f[0]; +} /* End of MSBINToIEEE */ + + +/* IEEEToMSBIN - Converts an IEEE floating point number */ +/* to MSBIN floating point format */ +/* */ +/* Input: f - floating point number in IEEE format */ +/* Output: Same number in MSBIN format */ + +float IEEEToMSBIN(float f) +{ + union Converter t; + int sign, exp; /* sign and exponent */ + + t.f[0] = f; + + /* extract sign & change exponent bias from 0x7f to 0x81 */ + + sign = t.uc[3] / 0x80; + exp = ((t.ui[1] >> 7) - 0x7f + 0x81) & 0xff; + + /* reassemble them in MSBIN format */ + + t.ui[1] = (t.ui[1] & 0x7f) | (sign << 7) | (exp << 8); + return t.f[0]; +} /* End of IEEEToMSBIN */ diff --git a/reference/C/CONTRIB/SNIP/msc_peek.c b/reference/C/CONTRIB/SNIP/msc_peek.c new file mode 100755 index 0000000..03ec54f --- /dev/null +++ b/reference/C/CONTRIB/SNIP/msc_peek.c @@ -0,0 +1,48 @@ +/* +** For MSC which lacks these very basic (sic) functions +** +** public domain by Bob Stout +*/ + +#include + +#ifndef MK_FP + #define MK_FP(seg,offset) \ + ((void _far *)(((unsigned long)(seg)<<16) | (unsigned)(offset))) +#endif + +unsigned char peekb(unsigned seg, unsigned ofs) +{ + unsigned char _far *ptr; + + FP_SEG(ptr) = seg; + FP_OFF(ptr) = ofs; + return *ptr; +} + +unsigned peek(unsigned seg, unsigned ofs) +{ + unsigned _far *ptr; + + FP_SEG(ptr) = seg; + FP_OFF(ptr) = ofs; + return *ptr; +} + +void pokeb(unsigned seg, unsigned ofs, unsigned char ch) +{ + unsigned char _far *ptr; + + FP_SEG(ptr) = seg; + FP_OFF(ptr) = ofs; + *ptr = ch; +} + +void poke(unsigned seg, unsigned ofs, unsigned num) +{ + unsigned _far *ptr; + + FP_SEG(ptr) = seg; + FP_OFF(ptr) = ofs; + *ptr = num; +} diff --git a/reference/C/CONTRIB/SNIP/mterm.c b/reference/C/CONTRIB/SNIP/mterm.c new file mode 100755 index 0000000..b022504 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/mterm.c @@ -0,0 +1,133 @@ +/* MTERM.C - Minimal example PC terminal program. + Released to public domain by author, David Harmon, June 1992. + Intended for use with a FOSSIL driver, but will run with BIOS alone. + I expect you'll want to add something for practical purposes. ;-) +*/ + +#include +#include +#include /* kbhit(), getch(), putch(), etc. */ +#include /* int86(), etc. */ + +#ifdef __ZTC__ + #define cputs(s) fputs((s),stderr) +#endif + +int port = 0; /* 0 = COM1:, 1 = COM2: etc. */ +int local_echo = 0; +int cr_add_lf = 0; +int exiting = 0; + +int init_comm(int flags) +{ + union REGS regs; + + regs.h.ah = 0x04; /* initialize driver (port) */ + regs.x.bx = 0x4f50; + regs.x.dx = port; + int86( 0x14, ®s, ®s); + + regs.h.ah = 0x00; /* set baud rate * port attrs */ + regs.h.al = (unsigned char)flags; + regs.x.dx = port; + int86( 0x14, ®s, ®s); + return regs.h.ah; +} + +void send_char(char ch) +{ + union REGS regs; + + regs.h.ah = 0x01; /* Send char (wait until ready)*/ + regs.h.al = ch; + regs.x.dx = port; + int86( 0x14, ®s, ®s); +} + +int input_ready(void) +{ + union REGS regs; + + regs.h.ah = 0x03; /* Get port status */ + regs.x.dx = port; + int86( 0x14, ®s, ®s); + return ((regs.h.ah & 0x01) != 0); /* input ready */ +} + +int get_char(void) +{ + union REGS regs; + + regs.h.ah = 0x02; /* receive char (wait if necessary)*/ + regs.x.dx = port; + int86( 0x14, ®s, ®s); + return regs.h.al; +} + +void deinit_comm(void) +{ + union REGS regs; + + regs.h.ah = 0x05; /* deinitialize port (pseudo close) */ + regs.h.al = 0x00; /* (lower DTR) */ + regs.x.dx = port; + int86( 0x14, ®s, ®s); +} + +void main(void) +{ + int ch; + + init_comm(0xE3); /* hard coded 0xB3 = 2400,N,8,1 */ + cputs("MTERM ready! Press F1 to exit.\r\n"); + while (!exiting) + { + if (kbhit()) /* key was hit */ + { + ch = getch(); /* Regular ASCII keys are returned as the + ASCII code; function keys, arrows, etc. + as zero followed by a special code + (on next getch.) */ + if (ch != 0) + { + send_char((char)ch); /* to com port */ + if (local_echo) + { + putch(ch); /* to screen */ + + /* add LF to CR? */ + + if (cr_add_lf && ch == '\r') + putch('\n'); + } + } + else + { + ch = getch(); /* get the special key code */ + switch (ch) + { + case 0x3B: /* F1 */ + exiting = 1; /* quit now */ + break; + + case 0x3C: /* F2 */ + local_echo = !local_echo; /* toggle echo */ + break; + + case 0x3D: /* F3 */ + cr_add_lf = !cr_add_lf; /* toggle LF */ + break; + } + } + } /* end if kbhit */ + + if (input_ready()) /* com port */ + { + ch = get_char(); + putch(ch); + if (cr_add_lf && ch == '\r') /* add LF to CR? */ + putch('\n'); + } + } /* end while not exiting */ + deinit_comm(); +} diff --git a/reference/C/CONTRIB/SNIP/mv.c b/reference/C/CONTRIB/SNIP/mv.c new file mode 100755 index 0000000..a049d45 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/mv.c @@ -0,0 +1,136 @@ +/* +** mv.c -- move or rename files or directories +** updated for multiple files, 5 jul 92, rlm +** placed in the public domain via C_ECHO by the author, Ray McVay +** +** modified by Bob Stout, 28 Mar 93 +** modified by Bob Stout, 4 Jun 93 +** +** uses file_copy from SNIPPETS file WB_FCOPY.C +*/ + +#include +#include +#include +#include + +/* For portability, make everything look like MSC 6 */ + +#if defined(__TURBOC__) + #include + #define _dos_findfirst(f,a,b) findfirst(f,b,a) + #define find_t ffblk + #define _A_SUBDIR FA_DIREC + #define attrib ff_attrib +#else /* assume MSC/QC */ + #include +#endif + +/* +** Tell 'em they messed up +*/ + +void help(char *s) +{ + puts("usage: mv "); + printf("error: %s\n", s); +} + +/* +** Simple directory test +*/ + +isdir(char *path) +{ + struct find_t f; + + /* "Raw" drive specs are always directories */ + + if (':' == path[1] && '\0' == path[2]) + return 1; + + return (_dos_findfirst(path, _A_SUBDIR, &f) == 0 && + (f.attrib & _A_SUBDIR)); +} + +/* +** Use rename or copy and delete +*/ + +int mv(char *src, char *dest) +{ + int errcount = 0; + char buf[FILENAME_MAX]; + const char *generr = "ERROR: mv - couldn't %s %s %s\n"; + + if (':' == dest[1] && *dest != *getcwd(buf, FILENAME_MAX)) + { + if (file_copy(src, dest)) + { + printf(generr, "move", src, dest); + ++errcount; + } + else if (unlink(src)) + { + printf(generr, "delete", src, ""); + ++errcount; + } + } + else + { + if (rename(src, dest)) + { + printf(generr, "rename", src, dest); + ++errcount; + } + } + return errcount; +} + +/* +** Enter here +*/ + +int main(int argc, char **argv) +{ + int src, errcount = 0; + char target[FILENAME_MAX]; + + puts("mv 1.3 (4 jun 93) - Ray L. McVay/Bob Stout"); + if (argc < 3) + help("Not enough parameters"); + + /* + ** Handle cases where target is a directory + */ + + else if (isdir(argv[argc -1])) + { + for (src = 1; src < argc - 1; src++) + { + char termch; + + strcpy(target, argv[argc - 1]); + termch = target[strlen(target) - 1]; + if ('\\' != termch && ':' != termch) + strcat(target, "\\"); + + if (strrchr(argv[src], '\\')) + strcat(target, strrchr(argv[src], '\\') + 1); + else if (argv[src][1] == ':') + strcat(target, argv[src] + 2); + else strcat(target, argv[src]); + + errcount += mv(argv[src], target); + } + } + + /* + ** Nothing left except 2 explicit file names + */ + + else if (argc == 3) + errcount += mv(argv[1], argv[2]); + + return errcount; +} diff --git a/reference/C/CONTRIB/SNIP/myio.cpp b/reference/C/CONTRIB/SNIP/myio.cpp new file mode 100755 index 0000000..efe6f59 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/myio.cpp @@ -0,0 +1,127 @@ +// Myio.cpp +// Simple I/O class to demonstrate use of C++ iostream +// facilities in a customised environment +// Written by David L Nugent, June 1993 + +# include +# include +# include "Myio.h" +# include "Mystream.h" + +Myio::Myio (int sz) + : bufsize(sz), bufchars(0), bufidx(0), + bufaddr(new char[bufsize]), mystream(0) +{} + +Myio::~Myio (void) +{ + delete bufaddr; + delete mystream; +} + +iostream & +Myio::stream (void) +{ + if (!mystream) // Create a stream if required + mystream = new Mystream(this); + return *mystream; +} + +int // Simple write function into a circular buffer +Myio::write (char const * buf, int len) +{ + int avail = (bufsize - bufchars); // See how many fit + if (len > avail) + { + len = avail; + stat |= Myio::overflow; // Only partial write + } + else + stat &= ~Myio::overflow; + avail = bufsize - bufidx; // Caculate room at end + if (avail > len) + avail = len; + if (avail) + { + memcpy (bufaddr + bufidx, buf, avail); + bufidx += avail; // Update the put index + buf += avail; // And the input pointer + } + if (bufidx >= bufsize) // Wrap buffer to start + bufidx = 0; + avail = len - avail; // See if there is any more to go + if (avail) + { + memcpy (bufaddr + bufidx, buf, avail); + bufidx += avail; // Update the put index + } + bufchars += len; + return (_pcount = len); +} + +int // Simple read function from a circular buffer +Myio::read (char * buf, int len) +{ + if (len > bufchars) // Adjust for available bytes + { + len = bufchars; + stat |= Myio::underflow; // Got an underflow (partial read) + } + else + stat &= ~Myio::underflow; // Clear underflow flag + int startidx = bufidx - bufchars; // Determine start get position + if (startidx < 0) + startidx += bufsize; // Adjust for wrap + int avail = bufsize - startidx; // Check room at end of buffer + if (avail > len) // Adjust down if necessary + avail = len; + if (avail) // Copy first section + { + memcpy (buf, bufaddr + startidx, avail); + startidx += avail; // Adjust start index + buf += avail; // Adjust output pointer + } + if (startidx >= bufsize) // Wrap buffer to start + startidx = 0; + avail = len - avail; // See if there is any more to go + if (avail) // If so, copy the rest + memcpy (buf, bufaddr + startidx, avail); + bufchars -= len; // Adjust character count + return (_gcount = len); +} + +Myio & +operator<< (Myio & m, char const * ptr) +{ + m.write (ptr, strlen (ptr)); + return m; +} + +int +Myio::dump (void) const +{ + if (bufchars) + { + char * tmp = new char[bufchars + 2]; + int idx = bufidx - bufchars; + if (idx < 0) + idx += bufsize; + for (int i = 0; i < bufchars; ) + { + if (idx >= bufsize) + idx = 0; + tmp[i++] = bufaddr[idx++]; + } + if (i) + { + if (tmp[i-1] != '\n') // Terminate with NL + tmp[i++] = '\n'; + tmp[i] = 0; + cout << "---\n" + << tmp + << "---\n"; + } + delete tmp; + } + return bufchars; +} diff --git a/reference/C/CONTRIB/SNIP/myio.h b/reference/C/CONTRIB/SNIP/myio.h new file mode 100755 index 0000000..d57dae4 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/myio.h @@ -0,0 +1,98 @@ +// Myio.h +// Specialised I/O class to demonstrate use of C++ iostream +// facilities in a customised environment +// Written by David L Nugent, June 1993. +// + +# if !defined(_Myio_h) +# define _Myio_h 1 + + // Foward declare classes + +class Myio; +class Mystreambuf; +class Mystreambase; +class Mystream; + + // Forward declare iostream classes + +class iostream; + + // + // class Myio + // This is a simplistic class which simply fields + // input and output to a simulated stream device. + // + // In fact, it doesn't really do much at all other + // than read input from and send output to a + // circular queue, as though talking via a loopback + // pipe to itself. + // + + +class Myio +{ + friend class Mystreambuf; + + public: + + Myio (int sz =2048); // sz = buffer size to allocate + virtual ~Myio (void); + + iostream & stream (void); // Return (or create) stream + + int readok (void) const; // Underflow check + int writeok (void) const; // Overflow check + int gcount (void) const; // Get # of chrs last read + int pcount (void) const; // Get # of chrs last written + int count (void) const; // Get # of chrs in buffer + int size (void) const; // Get size of buffer + int dump (void) const; // Debugging - dumps buffer + + int write (char const * buf, int len); // Put data into 'pipe' + int read (char * buf, int max); // Read data from our 'pipe' + + private: + + enum + { + overflow = 0x0001, // Last write only partial + underflow = 0x0002 // Last read only partial + }; + + unsigned stat; // Last read/write status + int _pcount; // Last write count + int _gcount; // Last read count + int bufsize; // Size of our buffer + int bufchars; // Chrs in buffer now + int bufidx; // Index into buffer (next put) + char * bufaddr; // Pointer to buffer + Mystream * mystream; // Stream assocated with this object + +}; + +inline int +Myio::readok (void) const + { return ((stat & Myio::underflow) == 0); } + +inline int +Myio::writeok (void) const + { return ((stat & Myio::overflow) == 0); } + +inline int +Myio::gcount (void) const + { return _gcount; } + +inline int +Myio::pcount (void) const + { return _pcount; } + +inline int +Myio::count (void) const + { return bufchars; } + +inline int +Myio::size (void) const + { return bufsize; } + +# endif // _Myio_h diff --git a/reference/C/CONTRIB/SNIP/myio.mak b/reference/C/CONTRIB/SNIP/myio.mak new file mode 100755 index 0000000..a058cf6 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/myio.mak @@ -0,0 +1,107 @@ +## +# Makefile for Myio project +# Created on 06/13/93 at 09:47 after a long night +## + +##### MSDOS & OS/2 extensions ##### + +X = .cpp +O = .obj +E = .EXE + +##### UNIX #### + +#X = .cc +#O = .o +#E = + +###### Borland C for OS/2 ###### +#M = 2 +#CC = bcc +#LD = tlink +#LIBPATH = F:\Bcc\lib +#INCLUDEPATH = F:\Bcc\include +#CFLAGS = -Oiabec -I$(INCLUDEPATH) -vi- -d -k- -w -a +#LDFLAGS = /x /Toe /ap /L$(LIBPATH) +#STARTUP = $(LIBPATH)\c0$(M)$(O) +#LDLIBS = C$(M).LIB OS2.LIB + +###### Borland C for MSDOS ###### +#M = S +#CC = bcc +#LD = tlink +#LIBPATH = F:\Bcc\lib.dos +#INCLUDEPATH = F:\Bcc\include.dos +#CFLAGS = -I$(INCLUDEPATH) -ms -Oiabec -k- -vi- -d -k- -w +#LDFLAGS = /L$(LIBPATH) +#STARTUP = $(LIBPATH)\c0$(M)$(O) +#LDLIBS = C$(M).LIB + +###### MicroSoft C/C++ for MSDOS ###### +#M = S +#CC = cl +#LD = link +#LIBPATH = F:\msc\lib +#INCLUDEPATH = F:\msc\include +#CFLAGS = -I$(INCLUDEPATH) -A$(M) -Oceglnota -W4 +#LDFLAGS = +#STARTUP = +#LDLIBS = ; + +###### Zortech C/C++ for MSDOS/OS/2 ###### +#M = s +#CC = ztc +#LD = blink +#LIBPATH = F:\zortech\lib +#INCLUDEPATH = F:\zortech\include +#CFLAGS = -I$(INCLUDEPATH) -m$(M) -o +#LDFLAGS = +#STARTUP = +#LDLIBS = ; + +###### Symantec C/C++ for MSDOS/Mac/OS/2 ###### +#M = s +#CC = sc +#LD = link +#LIBPATH = F:\symantec\lib +#INCLUDEPATH = F:\symantec\include +#CFLAGS = -I$(INCLUDEPATH) -m$(M) -o +#LDFLAGS = +#STARTUP = +#LDLIBS = ; + +###### IBM C++Set/2 for OS/2 ###### +M = +CC = icc +LD = link386 +LIBPATH = F:\IbmCpp\lib +INCLUDEPATH = F:\IbmCpp\include +CFLAGS = /Q /I$(INCLUDEPATH) /W2 /Wall /O /Oip +LDFLAGS = /NOLOGO/BAT/NOI/NOE/PM:VIO +LDLIBS = ; + +##### Implicit Rules #### + +.SUFFIXES: +.SUFFIXES: $(X) $(O) + +$(X)$(O): + $(CC) $(CFLAGS) -c $< + +TARGET = Myiodemo$(E) +OBJECTS = Myiodemo$(O) Myio$(O) Mystream$(O) myLine$(O) +AOBJECTS = $(STARTUP) $(OBJECTS) + +$(TARGET): $(OBJECTS) + $(LD) $(LDFLAGS) $(AOBJECTS),$@,,$(LDLIBS) +# $(LD) $(LDFLAGS) $(AOBJECTS) -o $@ $(LDLIBS) + +###### Dependancies ####### + +myLine$(O): myLine$(X) myLine.h + +Mystream$(O): Mystream$(X) Mystream.h Myio.h + +Myio$(O): Myio$(X) Mystream.h Myio.h + +Myiodemo$(O): Myiodemo$(X) myLine.h Myio.h Mystream.h diff --git a/reference/C/CONTRIB/SNIP/myiodemo.cpp b/reference/C/CONTRIB/SNIP/myiodemo.cpp new file mode 100755 index 0000000..52975d2 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/myiodemo.cpp @@ -0,0 +1,168 @@ +// Myiodemo.cpp +// This is a trivial program which uses the myio loopback class +// to demonstrate the basics on writing an io interface using +// the AT&T C++ iostream classes. +// The program simply provides the ability to selectively add +// to or read from a Myio instance and display information to +// assist in understanding how it all works. +// + +# include "Mystream.h" // This includes Myio.h and iostream.h +# include "myLine.h" +# include // For getch() +# include // For toupper() +# include + +# define NL char('\n') + + // Let's do the "application is a class" trick + +class myApplication +{ + // Defines a pointer to member function type + // used for dispatching the menu + + typedef void (myApplication::*pvf) (void); + + public: + + myApplication (void) : mio() {} + int execute (void); + + private: + + iostream & stream (void) { return mio.stream(); } + int domenu (void); + void send (void); + void read (void); + void disp (void); + void peek (void); + void flsh (void); + void stat (void); + + pvf choice; // Function called to execute + Myio mio; // IO object + +}; + + +void +myApplication::disp (void) +{ + cout << "Mystream status:" << NL + << "Chrs in output buffer = " << stream().rdbuf()->out_waiting() << NL + + << "Chrs in input buffer = " << stream().rdbuf()->in_avail() << NL + + << "Myio object status = " + << mio.count() << char('/') << mio.size() + << " LastWrite=" << (mio.writeok() ? "OK" : "Incomplete") + << " LastRead=" << (mio.readok() ? "OK" : "EOF") + << endl; +} + + // Request a line and send it to the IO device + +void +myApplication::send (void) +{ + cout << NL << "Enter text to write - press when done\n:"; + myLine L; + cin >> L; + int l = strlen(L); + if (!l) + cerr << "Nothing entered." << endl; + else + { + cout << "Writing '" + << L + << char('\'') + << endl; + stream() << L << NL; // Send the entered data, NL terminated + cout << "Chrs written to Myio object = " << (l + 1) << NL; + disp (); + } +} + +void +myApplication::read (void) +{ + cout << NL << "Reading a line from object:" << NL; + myLine L; + mio.stream().clear(); + mio.stream() >> L; + int l = strlen(L); + if (!l) + { + cout << "Nothing read." << endl; + mio.stream().clear(); // Clear EOF status + } + else + { + cout << "Read '" + << L + << char('\'') + << endl; + cout << "Chrs read from Myio object = " << (l + 1) << NL; + disp (); + } +} + +void +myApplication::flsh (void) +{ + cout << NL << "Flushing stream" << endl; + stream() << flush; + disp (); +} + +void +myApplication::stat (void) +{ + cout << NL << "Myio object buffer dump:" << NL; + mio.dump(); + disp (); + stream().rdbuf()->dbp(); // Dump stream info +} + +int +myApplication::domenu (void) +{ + cout << NL + << "W)rite R)ead D)ump F)lush Q)uit\n" + << "Select: " + << flush; // Need to flush here for portability + int key; + for (;;) + { + key = getch (); + switch (toupper(key)) + { + case 'W': choice = &myApplication::send; break; + case 'R': choice = &myApplication::read; break; + case 'D': choice = &myApplication::stat; break; + case 'F': choice = &myApplication::flsh; break; + case 'Q': key = 0; break; + default: + continue; + } + cout << char(key) << endl; + break; + } + return key; +} + +int // This is really the application +myApplication::execute (void) +{ + while (domenu ()) + (this->*choice) (); + return 0; +} + +int +main (void) +{ + myApplication Demo; // Declare the application + return Demo.execute (); // go for it! +} diff --git a/reference/C/CONTRIB/SNIP/myline.cpp b/reference/C/CONTRIB/SNIP/myline.cpp new file mode 100755 index 0000000..7182b3c --- /dev/null +++ b/reference/C/CONTRIB/SNIP/myline.cpp @@ -0,0 +1,76 @@ +// myLine.cpp +// +// 13 Jun 93 Init array[0] = NUL in case it is reference before use +// memcpy() adjusted to also copy terminating NUL from is.get() +// when extending buffer +// + +# include +# include "myLine.h" +# if defined(_MSC_VER) +# include +# else +# include +# endif + + // Class implementation + +myLine::myLine (short buflen) + : len(buflen), mybuf(new char[len]), xalloc(1) +{ + mybuf[0] = 0; +} + +myLine::myLine (char * usebuf, short buflen) + : len(buflen), mybuf(usebuf), xalloc(0) +{ + mybuf[0] = 0; +} + +myLine::~myLine (void) +{ + if (xalloc) + delete [] mybuf; +} + + +istream & +operator>> (istream & is, myLine & l) +{ +# if AUTO_GROW + if (!l.xalloc) // It's not my buf, so it can't be grown + { +# endif + is.get (l.mybuf, l.len); + if (is.peek() == '\n') + is.get(); // Remove newline from stream +# if AUTO_GROW + } + else + { + int idx = 0; + l.mybuf[0] = 0; // Terminate in case is.good() isn't + for (int eol = 0; !eol && is.good(); ) + { + int toget = l.len - idx; + is.get (l.mybuf + idx, toget); + int chrs = is.gcount(); + if (is.peek() == '\n') + { + ++eol; // Must be eol or eof + is.get(); // Clear newline + } + else if (chrs) + { // Extend buffer + idx += chrs; // Add to index + l.len = short(l.len + ALLOC_LEN); + char * tmp = new char[l.len]; + memcpy (tmp, l.mybuf, idx + 1); + delete [] l.mybuf; + l.mybuf = tmp; + } + } + } +# endif + return is; +} diff --git a/reference/C/CONTRIB/SNIP/myline.h b/reference/C/CONTRIB/SNIP/myline.h new file mode 100755 index 0000000..01e31e3 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/myline.h @@ -0,0 +1,43 @@ +// myLine.h +// +// Donated to the public domain; no restrictions on reuse or abuse apply. +// by David Nugent, 7th June, 1993. +// Simple line input class for istream to demonstrate input of a complete +// line rather than whitespace separated tokens (the default for operator<< +// for char* and other built-in types). +// Works by overloading operator>> for a customised class - this functionality +// is easily incorporated into your favourite String class +// + +# if !defined(_myLine_h) +# define _myLine_h 1 + +# define AUTO_GROW 1 // Allow autogrowth of buffer to fit +# define ALLOC_LEN 80 // Standard length & growth increment + + // Class declaration + +class myLine +{ + + public: + + myLine (short buflen =ALLOC_LEN); + myLine (char * usebuf, short buflen =ALLOC_LEN); + ~myLine (void); + // Get buffer address + char const * buf (void) const { return mybuf; } + // Conversion operators + char const * operator() (void) const { return mybuf; } // Explicit cast + operator char const * (void) const { return mybuf; } // Implicit cast + // istream operator>> + friend istream & operator>> (istream &, myLine &); + + private: + + short len, xalloc; + char * mybuf; + +}; + +# endif // _myLine_h diff --git a/reference/C/CONTRIB/SNIP/mystream.cpp b/reference/C/CONTRIB/SNIP/mystream.cpp new file mode 100755 index 0000000..4776728 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/mystream.cpp @@ -0,0 +1,142 @@ +// Mystream.cpp +// Implementation of ios interface classes for Myio +// +// Written by David L. Nugent +// + +# include +# include "Mystream.h" +# if defined(_MSC_VER) +# include +# else +# include +# endif + + // Mystreambuf constructor + // This simply initialises the base class streambuf + // (it is initially empty with no buffer allocated) + // and register the Myio object + // Note: we _could_ set the stream unbuffered here, + // which is useful for stdio handles, so that the + // streambuf functions overflow() and underflow() + // get called on every character rather than when + // the streambuf buffer is full + +Mystreambuf::Mystreambuf (Myio * mPtr) + : streambuf (), mptr(mPtr) +{ +// unbuffered(1); // Uncomment to make unbuffered +} + + // Mystreambuf() + // Called when streambuf owned buffer is full + // or when stream is flushed + // Our job here is to empty the streambuf + // write buffer and reset the 'put' pointers. + +int +Mystreambuf::overflow (int c) +{ + int written; + + // Handle unbuffered stream + + if (unbuffered()) // Handle the simple case first + { + if (c == EOF) // Special case, this only flushes + return 0; + char ch = char(c); // Write the byte directly + written = mptr->write (&ch, 1); + return (written) ? c : EOF; + } + + // Handle buffered stream + + if (!base()) // Need to allocate a buffer + allocate(); + + if (base()) // Test for memory allocation error + { + char * ep = base() + (blen() / 2); + if (!pbase()) // Set put pointers if not set up + setp (base(), ep); + int bytes = pptr() - pbase(); // Bytes to write + if (bytes) + { + written = mptr->write (pbase(), bytes); + if (!written) + return EOF; + bytes += written; + if (bytes) // Some is still waiting to be written + memcpy (base(), base() + written, bytes); + } + setp (base() + bytes, ep); // Reset 'put' pointers + return (c == EOF) ? 0 : sputc (c); // Put pending chr in buf + } + return EOF; +} + + // + // underflow() indicates that the input queue + // is empty and needs more data + // + +int +Mystreambuf::underflow (void) +{ + int bytes; + + // Handle an unbuffered stream + + if (unbuffered()) + { + bytes = mptr->read (&_back[1], 1); + if (!bytes) + { + setg (0, 0, 0); + return EOF; + } + setg (_back, _back + 1, _back + 2); + return (unsigned char)_back[1]; + } + + // Handle a buffered stream + + if (!base()) // Need to allocate a buffer + allocate(); + + if (base()) + { + char * gp = base() + blen() / 2; + if (gptr() >= egptr()) + { // Read into the buffer from stream + overflow (); // Flush output in case we need it + bytes = mptr->read (gp + 1, blen() / 2 - 1); + setg (gp, gp + 1, gp + bytes + 1); + } + if (gptr() < egptr()) // Get from buffer + return (unsigned char) *gptr(); + } + return EOF; +} + + // + // sync() needs to empty both put and get + // buffered. It will do this by calling + // overflow and simply resetting the get + // pointers to their default location. + // + +int +Mystreambuf::sync (void) +{ + if (!unbuffered()) + { + overflow (); // Force output + char * gp = base(); + setp (gp, gp + blen() / 2); + gp = base() + blen() / 2; + setg (0, 0, 0); + } + return 0; +} diff --git a/reference/C/CONTRIB/SNIP/mystream.h b/reference/C/CONTRIB/SNIP/mystream.h new file mode 100755 index 0000000..2c2a909 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/mystream.h @@ -0,0 +1,92 @@ +// Mystream.h +// iostream interface for class Myio +// Defines the following classes: +// Mystreambuf derived from streambuf - buffer management & I/O interface +// Mystreambase base class used for initialisation & object reference +// Myiostream customised iostream, derived from iostream/Mystreambase +// +// Written by David L Nugent, June 1993 +// + +# if !defined(_Mystream_h) +# define _Mystream_h 1 +# include +# include "Myio.h" + + // + // Mystreambuf + // This is the class which does all the actual I/O + // handling and (optional) buffer management + // + +class Mystreambuf : public streambuf +{ + + public: + + Mystreambuf (Myio * mPtr); + + protected: + + virtual int overflow (int = EOF); + virtual int underflow (); + virtual int sync (); + + private: + + Myio * mptr; // Points to the Myio instance to + // which this stream is attached + char _back[2]; // Holder for putback + +}; + + +class Mystreambase : public virtual ios +{ + + public: + + Mystreambase (Myio * mPtr); + Mystreambuf * rdbuf (void); + + protected: + + Mystreambuf mystreambuf; + +}; + +inline +Mystreambase::Mystreambase (Myio * mPtr) + : mystreambuf (mPtr) +{} + +inline Mystreambuf * +Mystreambase::rdbuf (void) + { return &mystreambuf; } + + +class Mystream : public Mystreambase, public iostream +{ + + public: + + Mystream (Myio * mPtr); + ~Mystream (void); +}; + + // + // class Mystream constructor + // This uses Mystreambase to set up the Mystreambuf + // which can then be used to initialise iostream. + // + +inline +Mystream::Mystream (Myio * m) + : Mystreambase (m), iostream (rdbuf()) +{} + +inline +Mystream::~Mystream (void) + {} + +# endif // _Mystream_h diff --git a/reference/C/CONTRIB/SNIP/ndpcheck.asm b/reference/C/CONTRIB/SNIP/ndpcheck.asm new file mode 100755 index 0000000..4f788ef --- /dev/null +++ b/reference/C/CONTRIB/SNIP/ndpcheck.asm @@ -0,0 +1,44 @@ + page 55, 132 + +; +; FUNCTION: ndp_check +; +; Require MASM 5.1 or later, or equivalent +; +; Assemble with: MASM /Mx /z ... +; TASM /jMASM /mx /z ... +; + +% .MODEL memodel,C ;Add model support via + ;command line macros, e.g. + ;MASM /Mx /Dmemodel=LARGE + + .CODE + +control dw 0 + +;--------------------------------------------------------------- +; +; Check for an NDP. +; +; Returns 0 if no coprocessor +; Returns 1 if coprocessor present + + PUBLIC ndp_check + +ndp_check PROC USES BX + xor BX,BX ; set up zero return + fninit ; try to initialize the NDP + mov byte ptr control+1,0 ; clear memory byte + fnstcw control ; put control word in memory + mov AH,byte ptr control+1 ; if AH is 03h, you got + cmp AH,03h ; an NDP on board !! + jne SHORT NDPbye + inc BX +NDPbye: + mov AX,BX + ret + +ndp_check ENDP + + end diff --git a/reference/C/CONTRIB/SNIP/noctrlc.c b/reference/C/CONTRIB/SNIP/noctrlc.c new file mode 100755 index 0000000..bbc8649 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/noctrlc.c @@ -0,0 +1,63 @@ +/****************************************************************/ +/* Name: noctrl() */ +/* Desc: captures interrput 9 so as to ignore ctrl-c,ctrl-break,*/ +/* ctrl-alt-del */ +/****************************************************************/ + +#include + +#if defined(__ZTC__) + #define INTERRUPT + #define FAR _far + #define ENABLE int_on + #define INPORTB inp + #define OUTPORTB outp +#else + #include + #if defined(__TURBOC__) + #define INTERRUPT interrupt + #define FAR far + #define ENABLE enable + #define INPORTB inportb + #define OUTPORTB outportb + #else + #define INTERRUPT _interrupt + #define FAR _far + #define ENABLE _enable + #define INPORTB inp + #define OUTPORTB outp + #endif +#endif + +extern void (INTERRUPT FAR *oldint9)(void); /* Caller must set this */ + +void INTERRUPT FAR noctrl(void) +{ + unsigned char byte; + static int flag; + + ENABLE(); + + if ((byte = (unsigned char)INPORTB(0x60)) == 29) + flag = 1; + + if (byte == 157) + flag = 0; + + if (!flag) + (*oldint9)(); + else switch (byte) + { + case 46 : /* yeah, these should be #defined! */ + case 70 : + case 56 : + case 83 : + byte = (unsigned char)INPORTB(0x61); + OUTPORTB(0x61,byte | 0x80); + OUTPORTB(0x61,byte); + OUTPORTB(0x20,0x20); + break; + default : + (*oldint9)(); + } +} diff --git a/reference/C/CONTRIB/SNIP/nonmsdos.txt b/reference/C/CONTRIB/SNIP/nonmsdos.txt new file mode 100755 index 0000000..d54be14 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/nonmsdos.txt @@ -0,0 +1,42 @@ +The following SNIPPETS files are either non-MS/PC-DOS specific or may be +easily ported to other environments: + +Cast.H Hilobyte.H Pi.H Round.H C_Lines.Awk +A2E.C Amalloc.C Ansiflen.C Ansiself.C Approx.C +Bascnvrt.C Bastrngs.C Bitarray.C Bitcnt_1.C Bitcnt_2.C +Bitfiles.C Bitops.C Bitstrng.C Bstr_I.C Bresnham.C +Calsupp.C Cant.C Checksum.C Combin.C Commafmt.C +Crc-16.C Crc-16F.C Crc_32.C Crypt.C Ctrlprnt.C +Cubic.C Dbl2Long.C Dblround.C Editgets.C Eng.C +Eval.C Factoryl.C Fcompare.C Fcopy.C Ferrorf.C +Fmtmoney.C Fpswitch.C Fscanbin.C Fsm.C Getstrng.C +Hexorint.C Howdy.C Hstr_I.C Initvars.C Isisbn.C +Ispow2.C Isqrt.C Jdn.C Lbitops.C Ldfloor.C +Ll_Msort.C Ll_Qsort.C Ltoa.C Ltostr.C Lv1Ws.C +Mainmain.C Mdalloc.C Memrev.C Mkdirs.C Moon_Age.C +Ord_Text.C Perm_Idx.C Pluraltx.C Rand1.C Rand2.C +Redir.C Rg_Isort.C Rg_Qsort.C1 Rg_Qsort.C2 Rg_Rand.C +Rg_Ssort.C Rmallws.C Rmlead.C Rmtrail.C Rndmize.C +Scanfrac.C Soundex.C Srchfile.C Sstrcpy.C Stats.C +Stptok.C Str27Seg.C Strftime.C Strrepl.C Strrev.C +Strsort.C Strucfil.C Style.C Tabtrick.C Toascii.C +Translat.C Trim.C Wb_Fcopy.C Weird.C Windchil.C +Wordwrap.C Xstrcat.C Xstrcmp.C C_Prec.Txt Storage.Typ +Rtlftrul.Txt Ptr_Help.Txt C_Port.Txt Enums.Txt Resource.Lst +Match.H Match.C Match.Doc Dirmask.C Patmat.C +Fln_Fix.C Getcmt.C Testcmt.C Scaldate.H Scaldate.C +Daynum.C Cal.C W_Wrap.H W_Wrap.C Center.C +Xfile.H Xfile.C Xtest.C Getopt3.C Getopts.H +Getopts.C Pbmsrch.C Bmhsrch.C Bmhisrch.C Bmhasrch.C +Strdup.C Strupr.C Iostutor.Txt Myio.H Myio.Cpp +Mystream.H Mystream.Cpp Myline.H Myline.Cpp Myiodemo.Cpp +Myio.Mak Str.Doc Str.H Str.C Mem.Txt +Toolkit.H Mem.H Mem.C 2Dlife.C Bigfac.C +Bincomp.C C_Cmnt.C Chbytes.C Cmdline.C Commconv.C +Factor.C Fraction.C Head.C Hexdump.C Ifactor.C +Inchcvrt.C Killff.C Log.C Lzhuf.C Maze_1.C +Maze_2.C Maze_3.C Mv.C Palndrom.C Permute1.C +Permute2.C Pi.C Pr.C Rdxcnvrt.C Remtab.C +Roman.C Split.C Stub.C Sunriset.C Tail.C +Uuencode.C Uudecode.C Wc.C Where.C Jgrep.C +Grep.C diff --git a/reference/C/CONTRIB/SNIP/noreset.c b/reference/C/CONTRIB/SNIP/noreset.c new file mode 100755 index 0000000..f8ff751 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/noreset.c @@ -0,0 +1,103 @@ +/* code to disable . */ +/* Compiled and tested under TC++ and MSC 6 */ + +#include +#include + +#if defined(__TURBOC__) + #define _interrupt interrupt + #define _far far +#else /* i.e. if MSC */ + #define inportb(port) inp(port) + #define outportb(port,val) outp(port,val) + #define enable() _enable() + #define disable() _disable() + #define getvect(int) _dos_getvect(int) + #define setvect(int,ptr) _dos_setvect(int,ptr) + unsigned char peekb(unsigned seg, unsigned ofs) + { + unsigned char far *ptr; + + FP_SEG(ptr) = seg; + FP_OFF(ptr) = ofs; + return *ptr; + } +#endif + +#define CTRLALT (0x08|0x04) /* bit flags set in kbstat() */ +#define DELSCAN 0x53 /* keyboard scan code for */ +#define KEYPORT 0x60 /* keyboard scan code port */ +#define CONTROLLERPORT 0x20 /* interrupt controller port */ +#define kbstat() peekb(0,0x417) /* BIOS data area - kb flags */ + +#define keyport() inportb(KEYPORT) + /* macro that returns the scancode of the key that caused */ + /* the interrupt */ + +#define install() (oldkbisr=getvect(0x09),setvect(0x09,newkbisr)) + /* installation macro, installs newkbisr() in the keyboard */ + /* interrupt chain */ + +#define uninstall() setvect(0x09,oldkbisr) + /* removal macro, call to remove newkbisr() from interrupt */ + /* chain. oldkbisr() must be removed before program ends */ + +void (_interrupt _far * oldkbisr)(void); + /* address of old keyboard ISR */ + +void _interrupt _far newkbisr(void) +{ + if((keyport()==DELSCAN)&&((kbstat()&CTRLALT)==CTRLALT)) + { + char kbin = (char)inportb(KEYPORT+1); /* reset keyboard */ + + outportb(KEYPORT+1, kbin|0x80); + outportb(KEYPORT+1, kbin); + disable(); + outportb(CONTROLLERPORT,0x20); /* tell controller to shut up */ + enable(); + } + else + oldkbisr(); /* chain to old keyboard isr */ +} + +#ifdef TEST + +#include +#include +#include +#include +#include + +void main(void) +{ + int ch = 0; + void cleanup(void), cbrk(int); + + install(); + atexit(cleanup); + + signal(SIGINT, cbrk); + + puts("This is a test of Ctrl-Alt-Del disabling."); + puts("Press any key, but only Esc should stop this program."); + + while (0x1b != ch) + { + if (kbhit) + ch = getch(); + } +} + +void cbrk(int sig) +{ + signal(SIGINT, SIG_IGN); + signal(SIGINT, cbrk); +} + +void cleanup(void) +{ + uninstall(); +} + +#endif diff --git a/reference/C/CONTRIB/SNIP/ord_text.c b/reference/C/CONTRIB/SNIP/ord_text.c new file mode 100755 index 0000000..6b37721 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/ord_text.c @@ -0,0 +1,33 @@ +/* +** Originally published as part of the MicroFirm Function Library +** +** Copyright 1991, Robert B.Stout +** +** Subset version with modifications suggested by Maynard Hogg +** released to the public domain, 1992 +** +** Function to return ordinal text. +*/ + +static char *text[] = {"th", "st", "nd", "rd"}; + +char *ordinal_text(int number) +{ + if (((number %= 100) > 9 && number < 20) || (number %= 10) > 3) + number = 0; + return text[number]; +} + +#ifdef TEST + +#include + +void main(void) +{ + int i; + + for (i = 0; i < 26; ++i) + printf("%d%s\n", i, ordinal_text(i)); +} + +#endif /* TEST */ diff --git a/reference/C/CONTRIB/SNIP/os_id.c b/reference/C/CONTRIB/SNIP/os_id.c new file mode 100755 index 0000000..95500f9 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/os_id.c @@ -0,0 +1,134 @@ +/* +** OS_ID.C +** +** based upon a public domain work by David Gibbs +*/ + +#define TEST +#define OS_ID_MAIN +#include "os_id.h" +#include + +struct i_os_ver id_os_ver[TOT_OS]; +int id_os_type; +int id_os; + +const char *id_os_name[TOT_OS] = { + "DOS", + "OS/2 DOS", + "DESQview", + "Windows Std", + "Windows 386" + }; + +int get_os (void) +{ + union REGS t_regs; + int osmajor, osminor; + + id_os_type = 0; + id_os = 0; + + /* test for DOS or OS/2 */ + + t_regs.h.ah = 0x30; + int86(0x21, &t_regs, &t_regs); + osmajor = t_regs.h.al; + osminor = t_regs.h.ah; + + if (osmajor < 10) + { + id_os_ver[DOS].maj = osmajor; + id_os_ver[DOS].min = osminor; + id_os_type = id_os_type | is_DOS; + } + else + { + /* OS/2 v1.x DOS Box returns 0x0A */ + + id_os_type = id_os_type | is_OS2; + + /* OS/2 v2.x DOS Box returns 0x14 */ + + id_os_ver[OS2].maj = osmajor/10; + id_os_ver[OS2].min = osminor; + } + + /* test for Windows */ + + t_regs.x.ax = 0x4680; + int86(0x2F, &t_regs, &t_regs); + + if (t_regs.x.ax == 0x0000) + { + id_os_ver[WINS].maj = 3; + id_os_ver[WINS].min = 0; + id_os_type = id_os_type | is_WINS; + } + else + { + t_regs.x.ax = 0x1600 ; + int86(0x2F, &t_regs, &t_regs); + + switch (t_regs.h.al) + { + case 0x00 : + case 0x80 : + case 0x01 : + case 0xFF : + break; + + default : + id_os_type = id_os_type | is_WIN3; + id_os_ver[WIN3].maj = t_regs.h.al; + id_os_ver[WIN3].min = t_regs.h.ah; + break ; + } /* endswitch */ + } /* endif */ + + /* Test for DESQview */ + + t_regs.x.cx = 0x4445; /* load incorrect date */ + t_regs.x.dx = 0x5351; + t_regs.x.ax = 0x2B01; /* DV set up call */ + + intdos(&t_regs, &t_regs); + if (t_regs.h.al != 0xFF) + { + id_os_type = id_os_type | is_DV; + id_os_ver[DV].maj = t_regs.h.bh; + id_os_ver[DV].min = t_regs.h.bl; + } + + if (id_os_type & is_DOS) + id_os = DOS; + if (id_os_type & is_WINS) + id_os = WINS; + if (id_os_type & is_WIN3) + id_os = WIN3; + if (id_os_type & is_DV) + id_os = DV; + if (id_os_type & is_OS2) + id_os = OS2; + + return(id_os); +} + + +#ifdef TEST + +#include + +int main(void) +{ + int ostype = get_os(); + + printf("%s version %d.%d\n", + id_os_name[ostype], + id_os_ver[ostype].maj, + id_os_ver[ostype].min); + + return(0); +} + +#endif diff --git a/reference/C/CONTRIB/SNIP/os_id.h b/reference/C/CONTRIB/SNIP/os_id.h new file mode 100755 index 0000000..bb53fdb --- /dev/null +++ b/reference/C/CONTRIB/SNIP/os_id.h @@ -0,0 +1,41 @@ +/* +** OS_ID.H +** +** Based upon a public domain work by David Gibbs +*/ + +#ifndef OS_ID_H +#define OS_ID_H + +struct i_os_ver +{ + int maj; + int min; +}; + +#define DOS 0 +#define OS2 1 +#define DV 2 +#define WINS 3 +#define WIN3 4 +#define TOT_OS 5 + + /* 76543210 */ +#define is_DOS 0x01 /* b'00000001' */ +#define is_OS2 0x02 /* b'00000010' */ +#define is_DV 0x04 /* b'00000100' */ +#define is_WINS 0x08 /* b'00001000' */ +#define is_WIN3 0x10 /* b'00010000' */ + +#ifndef OS_ID_MAIN + extern int id_os_type; + extern int id_os; + extern const char *id_os_name[TOT_OS]; + extern struct id_os_ver i_os_ver[TOT_OS]; +#endif + +/* Function prototypes */ +int get_os(); + +#endif /* OS_ID_H */ + diff --git a/reference/C/CONTRIB/SNIP/palndrom.c b/reference/C/CONTRIB/SNIP/palndrom.c new file mode 100755 index 0000000..70daad3 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/palndrom.c @@ -0,0 +1,2 @@ +/**/char q='"',*a="*//**/char q='%c',*a=%c%s%c*/};)b(stup;]d[b=]d-472[b)--d(elihw;)q,a,q,q,2+a,b(ftnirps;)b(stup{)(niam;731=d tni;]572[b," +,b[275];int d=137;main(){puts(b);sprintf(b,a+2,q,q,a,q);while(d--)b[274-d]=b[d];puts(b);}/*c%s%c%=a*,'c%'=q rahc/**//*"=a*,'"'=q rahc/**/ diff --git a/reference/C/CONTRIB/SNIP/patmat.c b/reference/C/CONTRIB/SNIP/patmat.c new file mode 100755 index 0000000..da20131 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/patmat.c @@ -0,0 +1,75 @@ +#include +#include + +/*********************************************************************** +** ** +** Function : patmat ** +** ** +** Purpose : Pattern Matching ** +** ** +** Usage : Pass two string pointers as parameters.The first ** +** being a raw string & the second a pattern the raw ** +** string is to be matched against.If the raw string ** +** matches the pattern,then the function returns a ** +** 1,else it returns a 0. ** +** ** +** e.g patmat("abcdefghi","*ghi") returns a 1. ** +** patmat("abcdefghi","??c??f*") returns a 1. ** +** patmat("abcdefghi","*dh*") returns a 0. ** +** patmat("abcdefghi","*def") returns a 0. ** +** ** +** The asterisk is a wild card to allow any charac- ** +** ters from its first appearance to the next spec- ** +** ific character.The character ? is a wild card ** +** for only one character in the position it appears.** +** Combinations such as "*?" or "?*" or "**" are ** +** illegal for obvious reasons & the functions may ** +** goof,though I think it will still work. ** +** ** +** Author : Sreenath Chary Nov 29 1988 ** +** ** +** Logic : The only simple way I could devise is to use ** +** recursion.Each character in the pattern is ** +** taken & compared with the character in the raw ** +** string.If it matches then the remaining amount ** +** of the string & the remaining amount of the ** +** pattern are passed as parameters to patmat again ** +** until the end of the pattern.If at any stage ** +** the pattern does not match,then we go back one ** +** level & at this level if the previous character ** +** was a asterisk in the pattern,we hunt again from ** +** where we left off,otherwise we return back one ** +** more level with a not found & the process goes ** +** on till the first level call. ** +** ** +** Only one character at a time is considered,except ** +** when the character is an asterisk.You'll get the ** +** logic as the program unfolds. ** +** ** +***********************************************************************/ + +patmat(char *raw,char *pat) +{ int i, slraw; + + if ((*pat == '\0') && (*raw == '\0')) /* if it is end of both */ + return( 1 ) ; /* strings,then match */ + if (*pat == '\0') /* if it is end of only */ + return( 0 ) ; /* pat tehn mismatch */ + if (*pat == '*') /* if pattern is a '*' */ + { if (*(pat+1) == '\0') /* if it is end of pat */ + return( 1 ) ; /* then match */ + for(i=0,slraw=strlen(raw);i<=slraw;i++)/* else hunt for match*/ + if ((*(raw+i) == *(pat+1)) || /* or wild card */ + (*(pat+1) == '?')) + if (patmat(raw+i+1,pat+2) == 1) /* if found,match */ + return( 1 ) ; /* rest of pat */ + } + else + { if (*raw == '\0') /* if end of raw then */ + return( 0 ) ; /* mismatch */ + if ((*pat == '?') || (*pat == *raw)) /* if chars match then */ + if (patmat(raw+1,pat+1) == 1) /* try & match rest of it*/ + return( 1 ) ; + } + return( 0 ) ; /* no match found */ +} diff --git a/reference/C/CONTRIB/SNIP/pbmsrch.c b/reference/C/CONTRIB/SNIP/pbmsrch.c new file mode 100755 index 0000000..ccbf41f --- /dev/null +++ b/reference/C/CONTRIB/SNIP/pbmsrch.c @@ -0,0 +1,95 @@ +/* +** A Pratt-Boyer-Moore string search, written by Jerry Coffin +** sometime or other in 1991. Removed from original program, and +** (incorrectly) rewritten for separate, generic use in early 1992. +** Corrected with help from Thad Smith, late March and early +** April 1992...hopefully it's correct this time. Revised by Bob Stout. +** +** This is hereby placed in the Public Domain by its author. +** +** 10/21/93 rdg Fixed bug found by Jeff Dunlop +*/ + +#include +#include +#include + +static size_t table[UCHAR_MAX]; +static size_t len; +static char *findme; + +/* +** Call this with the string to locate to initialize the table +*/ + +void init_search(const char *string) +{ + size_t i; + + len = strlen(string); + for (i = 0; i <= UCHAR_MAX; i++) /* rdg 10/93 */ + table[i] = len; + for (i = 0; i < len; i++) + table[(unsigned char)string[i]] = len - i - 1; + findme = (char *)string; +} + +/* +** Call this with a buffer to search +*/ + +char *strsearch(const char *string) +{ + register size_t shift; + register size_t pos = len - 1; + char *here; + size_t limit=strlen(string); + + while (pos < limit) + { + while( pos < limit && + (shift = table[(unsigned char)string[pos]]) > 0) + { + pos += shift; + } + if (0 == shift) + { + if (0 == strncmp(findme, + here = (char *)&string[pos-len+1], len)) + { + return(here); + } + else pos++; + } + } + return NULL; +} + +#ifdef TEST + +#include + +void main(void) +{ + char *here; + char *find_strings[] = {"abb", "you", "not", "it", "dad", "yoo", "hoo", + "oo", "oh", "xx", "xx", "x", "x", NULL}; + char *search_strings[] = {"cabbie", "your", "It isn't here", + "But it is here", "hodad", "yoohoo", "yoohoo", + "yoohoo", "yoohoo", "yoohoo", "xx", "x", "."}; + int i; + + for (i = 0; find_strings[i]; i++) + { + init_search(find_strings[i]); + here = strsearch(search_strings[i]); + printf("\"%s\" is%s in \"%s\"", find_strings[i], + here ? "" : " not", search_strings[i]); + if (here) + printf(" [\"%s\"]", here); + putchar('\n'); + } + +} + +#endif diff --git a/reference/C/CONTRIB/SNIP/pcnvrt.c b/reference/C/CONTRIB/SNIP/pcnvrt.c new file mode 100755 index 0000000..5e4ab51 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/pcnvrt.c @@ -0,0 +1,22 @@ +/* +** demo code for converting Pascal strings to/from C strings +** +** public domain by Bob Stout +*/ + +#include + +typedef unsigned char UCHAR; + +#define P2Cconvert(s) {UCHAR n = *(s); memmove((s), &(s)[1], n); s[n] = '\0';} +#define C2Pconvert(s) {int n = strlen(s); memmove(&(s)[1], (s), n); *(s) = n;} + +#if (0) /* Demo code fragment follows */ + + char string[81]; + + fgets(string, 81, inFile); /* get 80-char pascal string */ + P2Cconvert(string); /* convert it in place */ + C2Pconvert(string); /* convert back */ + +#endif diff --git a/reference/C/CONTRIB/SNIP/pdn.lst b/reference/C/CONTRIB/SNIP/pdn.lst new file mode 100755 index 0000000..6ed8c11 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/pdn.lst @@ -0,0 +1,184 @@ +1/11/94 =-=-=-=-PDN BBS List-=-=-=-= + +This list represents members of the Programmer's Distribution Network who +have indicated to me that they will accept file requests for PDN files, or +Downloads on the first call, or downloads after a validation program. This +list is by no means all-inclusive, but represents only those who have let me +know via netmail that they would like to be on the list. + +See *Note below for FTP access. + +KEY: +HST : USRobotics Courier HST 14.4k H16 : USRobotics Courier HST 16.8k +V32 : ITU-TS V.32 compliant V32B: ITU-TS V.32bis compliant +V32T: AT&T V.32terbo compliant VFC : Rockwell 28.8k V.FC (V.Fast Class) +CSP : Compucom CSP ZYX : ZyXEL 16.8k V.32bis +Z19 : ZyXEL 19.2k V.32bis A21 : USR 21.6 ASL extension of v32terb + +FQ: U=Unlisted OK, L=only in nodelist N=No freqs 4=4d pts allowed +DL: Y=on first call, V=after validation, L=Long Distance Validation N=n/a +PDN: PDNAI = I PDNLANG = L PDNCEE = C PDNOTHER = T PDNWIN = W + PDNASM = A PDNNEWS = E PDNGNDOS= D PDNPASCL = P PDNVBWIN=N + PDNBASIC= B PDNOS2 = O PDNGNU = G PDNUNIX = U PDNVBDOS=V + + X = All areas !n = Not this area, but all others where n=above code + N = awaiting feedback, not all areas carried. +Hrs: A=anytime but ZMH, or listed times +Node: FidoNet Node Number or UL=not in nodelist + + += *USA* ================================================================ +St: Phone: Type: Fq: DL: PDN Hrs: Node: +========================================================================== +AL 1-205-666-0932 HST L L X 17:00-24:00 1:3625/454 +AZ 1-602-944-0524 V32B U V !G!U A 1:114/161 +CA 1-619-466-9505 HST L Y X A 1:202/302 +CA 1-714 939-6401 HST V32B U Y X A 1:103/208 +CA 1-310-375-1521 V32B U Y X 03:00-01:00 1:102/344 +CO 1-719-380-8813 H16 V32B U Y X A 1:128/60 +CO 1-303-674-0147 V32B U Y X A 1:104/825 +CT 1-203-879-7122 V32B U Y X A 1:141/1135 + 8:909/5(RBBS) +DE 1-302-995-6910 V32B U Y P A 1:150/170 +FL 1-904-494-6782 V32B L V X A 1:3612/370 +FL 1-407-773-0831 HST V32B U Y X A 1:374/38 +GA 1-912-953-1053 V32B L L ABCPOEL A 1:3611/15 +IL 1-708-680-9420 HST V32b Y Y X A 1:115/858 +KS 1-913-599-4626 ZYX L Y X A 1:280/314 +LA 1-504-386-8827 V32B U Y X A 1:394/7 +MA 1-508-250-0187 H16 V32B U V X A 1:324/287 +MA 1-508-250-4672 H16 V32B U V X A 1:324/288 +MA 1-508-256-1222 H16 V32B U V X A 1:324/291 +MA 1-508-250-0135 H16 V32B U V X A 1:324/292 +MD 1-410-256-0170 V32B U Y !W!G!U A 1:261/1082 +MN 1-612-788-6685 V32B U Y X A 1:282/2007 +MS 1-601-467-0801 V32 U Y X A 1:3604/15 +NJ 1-908-271-5168 H16 V32B U Y X A 1:107/302 +NY 1-518-761-0869 HST U V X A 1:267/54 +NY 1-212-927-4980 H16 V32B U Y X A 1:278/707 +NY 1-315-564-5700 V32B U Y X 03:00-04:00 EST 1:2608/15 +NY 1-315-773-2099 HST V32B L Y X A 1:2608/89 +NY 1-716-381-8538 HST V32 U V X A 1:2613/210 +NY 1-716-898-4366 HST V32 U Y X A 1:260/1 +NY 1-914-374-3903 HST L Y ABENV A 1:272/34 +NY 1-914-344-0350 H16 A21 U Y X A 1:272/38 +NY 1-914-343-7540 HST V32B U Y X A 1:272/100 +NC 1-919-286-7738 HST V32B U V X A 1:3641/1 +NC 1-919-286-4542 ZYX V32B U V X A 1:3641/224 +NV 1-702-873-0614 H16 V32B U Y X !0800-1800 M-F 1:209/710 +OH 1-419-478-7333 VFC U Y X A 1:234/56 +OH 1-216-628-4860 Z19 V32B U V CP A 1:157/534 +OK 1-918-438-8260 H16 V32b U Y X A 1:170/403 +TX 1-210-496-6550 HST U Y B A 1:387/403 +TX 1-210-675-4787 V32 U Y X 05:00-02:30 1:387/666 +TX 1-512-573-0245 HST V32B U Y X A 1:3802/213 +TX 1-817-855-1526 V32B U Y P A 1:3805/13 +VT 1-802-223-7951 V32 U Y B A 1:325/609 +WY 1-307-682-6944 HST V32B L Y ABCPTL 00:30-24:00A 1:15/24 + + += *Australia* ============================================================== +St: Phone: Type: Fq: DL: PDN Hrs: Node: +========================================================================== +VIC 61-3-338-3794 V32 Y Y X A 3:635/544 +Innaloo 61-9-244-2111 V32 Y V X A 3:690/660 +Innaloo 61-9-244-2111 V32 Y V X A 3:690/500 +Innaloo 61-9-244-2111 V32 Y V X A 3:690/0 +Essendn 61-3-301-1877 V32 Y N/A X A 3:50/99 + + += *Austria* ============================================================== +Vienna 43-1-290-3658 Z19 V32B U Y X A 2:310/24 + + += *Belgium* ============================================================== +Antwerp 32-3-2343790 V32B V42B U Y X A 2:292/855 + + += *Canada* =============================================================== +Ontario 1-613-837-0413 V32B U V X A 1:163/319 +Ontario 1-416-482-7097 ZYX V42B U N N 01:00-06:00EDT 1:250/820 +Ontario 1-613-548-7744 H16 V32b U Y P A 1:249/1 +Sask. 1-306-463-3117 H16 V32B U Y X A 1:140/53 +Sask. 1-306-463-4581 V32B N Y X A UL +Sask. 1-306-585-0298 HST Y Y X A 1:140/40 +Quebec 1-418-648-9590 V32B L V X 6am-3am 1:240/507 +Quebec 1-418-648-0691 V32B L V X 6am-3am EDT 1:240/508 +TroisRi 1-819-372-0467 V32B L Y OCEW A 1:167/710 +Vancvr 1-604-945-9384 H16 V32B U Y P A 1:153/740 + + += *Denmark* ============================================================== +St: Phone: Type: Fq: DL: PDN Hrs: Node: +========================================================================== +Aarhus +45-86-176232 H14 V32B L V X 8am-2am CET 2:230/22 +Aarhus +45-86-143158 H14 V32B L V X 9am-1am CET 2:230/8 +Aarhus +45-86-143599 2400b L V X 9am-1am CET 2:230/172 +Aarhus +45-86-143231 2400b L V X 9am-1am CET 2:230/173 +Aarhus +45-86-936822 Z19 L V X 7am-1am CET 2:230/73 +Aarhus +45-86-119615 Z19 L V X 8am-2am CET 2:234/48 +Aalborg +45-98-109446 HST V32B L N X 22pm-06am CET 2:230/914 +Cph. +45-47-380514 H16 V32B L V X 8am-2am CET 2:230/100 +Cph +45-31-241013 ZYX L V X 9am-2am CET 2:230/329 +Vordingb. +45-55-342345 Z19 U Y X 8am-5am CET 2:230/64 +Vordingb. +45-55-341345 H16 V32B U Y X 8am-5am CET 2:230/88 + + +=France ================================================================== +Wervicq-Sud 33-20392225 H16 V32B L V X A 2:322/2 +Wervicq-Sud 33-20399342 H16 V32B L V X A 2:322/3 +Wervicq-Sud 33-20392236 H16 V32B L V X A 2:322/4 + + += Germany ================================================================ +Kronberg+49-6173-1499 H14/V32B U V X 08-18/19-24 2:244/1540 +Kronberg+49-6173-940246 Z19/V32B U V X 06-24 2:244/1541 + + += Italy ================================================================= +Malgesso 39-332-706469 H16 V32B U Y X A 2:331/106 +Malgesso 39-332-706739 HST V32B U Y X A 2:331/117 +Malgesso 39-332-706009 ZYX V32B U Y X A 2:331/121 +Biandrnno 39-332-767277 HST V32B U Y X A 2:331/110 +Biandrnno 39-332-819044 ZYX V32B U Y X A 2:331/118 +Biandrnno 39-332-767329 ZYX V32B U Y X A 2:332/122 + + += *Luxembourg* =========================================================== +Strassen +352-316702 ZYX V32B U Y!I!W!B A 2:270/17 + + += *Netherlands* ========================================================= +Delden 31-5407-64701 HST V32B U Y X 8am-12pm CET 2:283/309 + 2:283/309 +Den Bosh 31-73-222164 HST V32B N Y X 6am-3am CET 2:512/152 +Eck & Wiel 31-3449-1909 V21 V22 U Y N 8am-2pm 2:500/137 + V32B V42B +Groningen 31-50-735035 HST V32B U Y X 8am-12pm CET 2:512/159 +Tilburg 31-13-674745 ZYX U Y P A 2:285/228 +Venlo 31-77-547521 ZYX V32B U Y !W!O 6am-1am CET 2:512/222.17 +Drieber. 31-3438-14125 H16 V32B U Y X A 2:512/169 +Zwijndrecht 31-78-196010 ZYX U N X 4:01-23:00 UTC 2:285/304 + + += *Sweden* =============================================================== +Lerum 46-302-16565 V32B U V X 07:00-23:00 2:203/311 +========================================================================== + +*Note: + PDN Files are available via Anonymous-FTP from ftpbone@ftp.fidonet.org (and + mirrored to ftpbone.halcyon.com) in the pub/fidonet/pdn directories. IP + Address 140.98.2.1 + + File Arrival Announcement messages are available on Internet via mailing + list. To be added to the mailing-list send e-mail to: + + listproc@ftpbone.fidonet.org with a single line of 'help'. + +If you carry the Programmer's Distribution Network and would like to be added +to this list, please send netmail to Janis Kracht 1:272/38, < pit[j]) + index ++; + } + index *= size - i; + } + return index; +} diff --git a/reference/C/CONTRIB/SNIP/permute1.c b/reference/C/CONTRIB/SNIP/permute1.c new file mode 100755 index 0000000..091ffa1 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/permute1.c @@ -0,0 +1,114 @@ +#include +#include + +/* chouse_n ( char *strng, int length) returns a pointer to a string of */ +/* length characters chosen from "strng" , duplicate chars in "strng" are */ +/* significant. Strings are generated in lexical order. */ +/* First call, call with *strng. each subsiquent call, call with NULL, */ +/* returns one combination. Calls after all combinations have been */ +/* returned return NULL. Will return NULL for errors. */ +/* not very defensive (i.e. WILL BREAK) */ + +/* dave chapman aug '91 released to public domain */ + +char *chouse_n( char *strng, int length); + +char *chouse_n( char *strng, int length) +{ + static char *str; + static char *curr; + static char *pos; /* for each char in curr(ent string), + its pos in str */ + static int counts[256]; + int i,j; + + if (0 >= length) + return NULL; + + if (NULL != strng) + { + str = malloc(strlen(strng)); /* first call, prep string for use */ + curr = malloc(2 * length + 1); + pos = curr + length +1; + + for (i = 0; i < 256; counts[i++] = 0) + ; + for (i = 0; strng[i]; i++) + counts[strng[i]]++; + + for (i = 1, j = 0; i < 256; i++) + { + if (counts[i]) + { + str[j] = i; + counts[j++] = counts[i]; + } + } + str[j] = '\0'; /* str is string of distinct chars in order */ + /* counts[] holds count of each char */ + + /* take first length chars */ + + for (i = 0,j = 0; i < length; i++) + { + curr[i] = str[j]; + pos[i] = j; + if (!(--counts[j])) + j++; + } + curr[i] = '\0'; + return curr; + } + /* if called with "mississippi",5; + str -> "imps" + curr -> "iiiim" + counts -> 0,0,2,4; + pos -> 0,0,0,0,1; */ + + /* go back to front */ + + for (j = length; j > 0;) + { + counts[ pos[--j]]++; /* "replace" char */ + + /* look for a new char for curr posit. */ + + for ( i = ++pos[j]; str[i] && ! counts[i]; i++) + ; + if (0 != (curr[j] = str[i])) /* found a char */ + { + --counts[i]; + pos[j] = i; + + /* placed char, fill out rest of string */ + + for (++j, i = 0; j < length; j++) + { + for ( ; !counts[i]; i++) + ; + curr[j] = str[i]; /* first available char */ + --counts[i]; + pos[j] = i; + } + return curr; + } + /* no more chars for this pos ; go back one */ + } + /* done */ + return NULL; +} + +void main(void) +{ + char *str = "aabbccdd"; + int i,j; + + j = 0; + i = 5; + puts(chouse_n( str, i)); + while (NULL != (str = chouse_n(NULL, i))) + { + ++j; + printf(" %s %d\n",str,j); + } +} diff --git a/reference/C/CONTRIB/SNIP/permute2.c b/reference/C/CONTRIB/SNIP/permute2.c new file mode 100755 index 0000000..2cad78a --- /dev/null +++ b/reference/C/CONTRIB/SNIP/permute2.c @@ -0,0 +1,79 @@ +/* +** PERMUTE.C - prints all permutations of an input string +** +** public domain demo by Jon Guthrie +*/ + +#include +#include +#include + +int charcmp(char *, char *); + +void permute(char *, int, int); + +int main(int argc, char *argv[]) +{ + int length; + + if (2 > argc) + { + puts("Usage: PERMUTE string"); + abort(); + } + + length = strlen(argv[1]); + + /* It only works if they're printed in order */ + + qsort(argv[1], length, 1, (int(*)(const void *, const void *))charcmp); + + permute(argv[1], 0, length); + return 0; +} + + +/* +** This function prints all of the permutations of string "array" +** (which has length "len") starting at "start." +*/ + +void permute(char *array, int start, int len) +{ + int j; + char *s; + + if(start < len) + { + if(NULL == (s = malloc(len))) + { + printf("\n\nMemory error!!!\a\a\n"); + abort(); + } + + strcpy(s, array); + for(j=start ; j +#include +#include + +#ifdef unix + #define SEP_CHARS ":" +#else + #define SEP_CHARS ";" +#endif + +FILE *pfopen(const char *name, const char *mode, const char *dirs) +{ + char *ptr; + char *tdirs; + FILE *file = NULL; + + if (dirs == NULL || dirs[0] == '\0') + return NULL; + + if ((tdirs = malloc(strlen(dirs)+1)) == NULL) + return NULL; + + strcpy(tdirs, dirs); + + for (ptr = strtok(tdirs, SEP_CHARS); file == NULL && ptr != NULL; + ptr = strtok(NULL, SEP_CHARS)) + { + size_t len; + char work[FILENAME_MAX]; + + strcpy(work, ptr); + len = strlen(work); + if (len && work[len-1] != '/' && work[len-1] != '\\') + strcat(work, "/"); + strcat(work, name); + + file = fopen(work, mode); + } + + free(tdirs); + + return file; +} + +#ifdef TEST + +int main(int argc, char **argv) +{ + FILE *file; + + if (argc != 4) + { + fprintf(stderr, "usage: pfopen name mode dirs\n"); + exit(1); + } + + file = pfopen(argv[1], argv[2], argv[3]); + + printf("%s \"%s\" with mode \"%s\"\n", (file == NULL) ? + "Could not open" : "Opened", argv[1], argv[2]); + + return 0; +} + +#endif diff --git a/reference/C/CONTRIB/SNIP/pi.c b/reference/C/CONTRIB/SNIP/pi.c new file mode 100755 index 0000000..11c71f4 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/pi.c @@ -0,0 +1,155 @@ +/* +** PI.C - Computes Pi to an arbitrary number of digits +** +** Uses far arrays so may be compiled in any memory model +*/ + +#include +#include + +#if defined(__ZTC__) + #include + #define FAR _far + #define Fcalloc farcalloc + #define Ffree farfree + #define Size_T unsigned long +#elif defined(__TURBOC__) + #include + #define FAR far + #define Fcalloc farcalloc + #define Ffree farfree + #define Size_T unsigned long +#else /* assume MSC/QC */ + #include + #define FAR _far + #define Fcalloc _fcalloc + #define Ffree _ffree + #define Size_T size_t +#endif + +long kf, ks; +long FAR *mf, FAR *ms; +long cnt, n, temp, nd; +long i; +long col, col1; +long loc, stor[21]; + +void shift(long FAR *l1, long FAR *l2, long lp, long lmod) +{ + long k; + + k = ((*l2) > 0 ? (*l2) / lmod: -(-(*l2) / lmod) - 1); + *l2 -= k * lmod; + *l1 += k * lp; +} + +void yprint(long m) +{ + if (cnt 9) + { + wk = m / 10; + m %= 10; + for (wk1 = loc; wk1 >= 1; wk1--) + { + wk += stor[(int)wk1]; + stor[(int)wk1] = wk % 10; + wk /= 10; + } + } + } + stor[(int)(++loc)] = m; +} + +void memerr(int errno) +{ + printf("\a\nOut of memory error #%d\n", errno); + if (2 == errno) + Ffree(mf); + _exit(2); +} + +int main(int argc, char *argv[]) +{ + int i=0; + char *endp; + + stor[i++] = 0; + if (argc < 2) + { + puts("\aUsage: PI "); + return(1); + } + n = strtol(argv[1], &endp, 10); + if (NULL == (mf = Fcalloc((Size_T)(n + 3L), (Size_T)sizeof(long)))) + memerr(1); + if (NULL == (ms = Fcalloc((Size_T)(n + 3L), (Size_T)sizeof(long)))) + memerr(2); + printf("\nApproximation of PI to %ld digits\n", (long)n); + cnt = 0; + kf = 25; + ks = 57121L; + mf[1] = 1L; + for (i = 2; i <= (int)n; i += 2) + { + mf[i] = -16L; + mf[i+1] = 16L; + } + for (i = 1; i <= (int)n; i += 2) + { + ms[i] = -4L; + ms[i+1] = 4L; + } + printf("\n 3."); + while (cnt < n) + { + for (i = 0; ++i <= (int)n - (int)cnt; ) + { + mf[i] *= 10L; + ms[i] *= 10L; + } + for (i =(int)(n - cnt + 1); --i >= 2; ) + { + temp = 2 * i - 1; + shift(&mf[i - 1], &mf[i], temp - 2, temp * kf); + shift(&ms[i - 1], &ms[i], temp - 2, temp * ks); + } + nd = 0; + shift((long FAR *)&nd, &mf[1], 1L, 5L); + shift((long FAR *)&nd, &ms[1], 1L, 239L); + xprint(nd); + } + printf("\n\nCalculations Completed!\n"); + Ffree(ms); + Ffree(mf); + return(0); +} diff --git a/reference/C/CONTRIB/SNIP/pi.h b/reference/C/CONTRIB/SNIP/pi.h new file mode 100755 index 0000000..3e9d415 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/pi.h @@ -0,0 +1,6 @@ +#ifndef PI + #define PI (4*atan(1)) +#endif + +#define deg2rad(d) ((d)*PI/180) +#define rad2deg(r) ((r)*180/PI) diff --git a/reference/C/CONTRIB/SNIP/playdemo.c b/reference/C/CONTRIB/SNIP/playdemo.c new file mode 100755 index 0000000..0597510 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/playdemo.c @@ -0,0 +1,37 @@ +/* +** PLAYDEMO.C - demo of background music functions +** +** public domain by Bob Stout +*/ + +#include +#include "uclock.h" +#include "sound.h" + +main() +{ + int i; + + if (!playb_open(1024)) + { + puts("\aError opening play buffer"); + return -1; + } + playb_note(C3, 8); + playb_note(REST, 2); + playb_note(C3, 8); + playb_note(REST, 2); + playb_note(E3, 8); + playb_note(REST, 2); + playb_note(E3, 8); + playb_note(REST, 2); + playb_note(G3, 8); + playb_note(REST, 2); + playb_note(G3, 8); + playb_note(REST, 2); + playb_note(E3, 18); + playb_note(REST, 2); + for (i = 0; i < 500; ++i) + printf("i = %d\n", i); + playb_close(); +} diff --git a/reference/C/CONTRIB/SNIP/playlib.c b/reference/C/CONTRIB/SNIP/playlib.c new file mode 100755 index 0000000..5ac3ddd --- /dev/null +++ b/reference/C/CONTRIB/SNIP/playlib.c @@ -0,0 +1,137 @@ +/* +** PLAYLIB.C +** +** Public domain for TC only by Lynn R. Lively +** Modified by Bob Stout +*/ + +#include +#include +#include "sound.h" + +#ifdef __ZTC__ + #include + #define interrupt +#else + static void (interrupt far *n_oldtmint) (void); +#endif + +#define TIMER_TICK_INTR 0x1c + +static NOTE * n_buff; +static unsigned n_buff_sz; +static NOTE * n_head; +static NOTE * n_tail; +static unsigned play_duration; +static unsigned play_freq; + +/* +** Add note to note buff. Return = 1 (note added), 0 (Out of note buff) +*/ + +int playb_note (unsigned freq, unsigned duration) +{ + if (++n_tail == (n_buff + n_buff_sz)) + n_tail = n_buff; + + if (n_tail == n_head) + { + --n_tail; + return (0); + } + + n_tail->freq = freq; + n_tail->duration = duration; + + return (1); +} + +/* +** ISR for background music. +*/ + +#ifndef __ZTC__ + static void interrupt far play_intr (void) +#else + static int play_intr (struct INT_DATA *idp) +#endif +{ + int_off (); + +#ifndef __ZTC__ + (*n_oldtmint) (); /* Call Old timer interrupt. */ +#else + int_prev(idp); +#endif + + if (play_duration == 0) + { + soundoff (); + + if (++n_head == (n_buff + n_buff_sz)) + n_head = n_buff; + + if (n_head == n_tail) + { + --n_head; + int_on (); + return; + } + + play_duration = n_head->duration; + if (0 != (play_freq = n_head->freq)) + soundon(); + dosound (play_freq); + } + else --play_duration; + + int_on (); + +#ifdef __ZTC__ + return 1; /* Don't chain */ +#endif +} + +/* +** Call this function to init background music. buff_sz is number of +** notes in the note buffer. Returns pointer to buff or NULL if +** out of heap space. +*/ + +NOTE * playb_open (unsigned buff_sz) +{ + n_buff = + n_head = + n_tail = (NOTE *) calloc (buff_sz, sizeof (NOTE)); + + if (n_buff != (NOTE *) NULL) + { + n_buff_sz = buff_sz; + + play_duration = + play_freq = 0; + +#ifdef __ZTC__ + int_intercept(TIMER_TICK_INTR, play_intr, 256); +#else + n_oldtmint = getvect (TIMER_TICK_INTR); + setvect (TIMER_TICK_INTR, play_intr); +#endif + } + return (n_buff); +} + +/* +** Return things to normal and free allocated space. +*/ + +void playb_close (void) +{ + soundoff (); +#ifndef __ZTC__ + setvect (TIMER_TICK_INTR, n_oldtmint); +#else + int_restore(TIMER_TICK_INTR); +#endif + free (n_buff); +} diff --git a/reference/C/CONTRIB/SNIP/pluraltx.c b/reference/C/CONTRIB/SNIP/pluraltx.c new file mode 100755 index 0000000..b0a616b --- /dev/null +++ b/reference/C/CONTRIB/SNIP/pluraltx.c @@ -0,0 +1,19 @@ +/* +** PLURALTX.C - How to print proper plurals +** +** public domain - original algorithm by Bob Stout +*/ + +#include + +#define plural_text(n) &"s"[(1 == (n))] +#define plural_text2(n) &"es"[(1 == (n)) << 1] + +void main(void) +{ + int i; + + for (i = 0; i < 10; ++i) + printf("%d thing%s in %d box%s\n", i, plural_text(i), + i, plural_text2(i)); +} diff --git a/reference/C/CONTRIB/SNIP/pmerge.c b/reference/C/CONTRIB/SNIP/pmerge.c new file mode 100755 index 0000000..3b219b1 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/pmerge.c @@ -0,0 +1,69 @@ +/* +** pmerge() - Portable replacement for fnmerge(), _makepath(), etc. +** +** Forms a full DOS pathname from drive, path, file, and extension +** specifications. +** +** Arguments: 1 - Buffer to receive full pathname +** 2 - Drive +** 3 - Path +** 4 - Name +** 5 - Extension +** +** Returns: Nothing +** +** public domain by Bob Stout +*/ + +#include + +#define LAST_CHAR(s) ((s)[strlen(s) - 1]) + +void pmerge(char *path, char *drive, char *dir, char *fname, char *ext) +{ + *path = '\0'; + + if (drive && *drive) + { + strcat(path, drive); + if (':' != LAST_CHAR(path)) + strcat(path, ":"); + } + + if (dir && *dir) + { + char *p; + + strcat(path, dir); + for (p = path; *p; ++p) + if ('/' == *p) + *p = '\\'; + if ('\\' != LAST_CHAR(path)) + strcat(path, "\\"); + } + + if (fname && *fname) + { + strcat(path, fname); + + if (ext && *ext) + { + if ('.' != *ext) + strcat(path, "."); + strcat(path, ext); + } + } +} + +#ifdef TEST + +#include + +int main(int argc, char *argv[]) +{ + char pathname[FILENAME_MAX]; + + pmerge(pathname, argv[1], argv[2], argv[3], argv[4]); + printf("pmerge (%s, %s, %s, %s) returned:\n %s\n", + argv[1], argv[2], argv[3], argv[4], pathname); +} diff --git a/reference/C/CONTRIB/SNIP/portable.h b/reference/C/CONTRIB/SNIP/portable.h new file mode 100755 index 0000000..5acb46d --- /dev/null +++ b/reference/C/CONTRIB/SNIP/portable.h @@ -0,0 +1,166 @@ +/*============================================================================ + + portable.h v1.00 Written by Scott Robert Ladd. + + _MSC_VER Microsoft C 6.0 and later + _QC Microsoft Quick C 2.51 and later + __TURBOC__ Borland Turbo C, Turbo C++, and Borland C++ + __BORLANDC__ Borland C++ + __ZTC__ Zortech C++ and Symantec C++ + __SC__ Symantec C++ + __WATCOM__ WATCOM C + __POWERC Mix Power C + + Revised: + 09/14/93 Fred Cole Moved MK_FP() macro to end of file to avoid + redefinition error when dos.h gets included + at the in/outport definitions for __TURBOC__ + 09/15/93 Thad Smith Add conditional code for TC 2.01 + Fix findfirst/findnext support for ZTC 3.0 + 10/15/93 Bob Stout Revise find first/next support + 04/03/94 Bob Stout Add Power C support, FAR +============================================================================*/ + + +/* prevent multiple inclusions of this header file */ + +#if !defined(PORTABLE_H) +#define PORTABLE_H + +/* +** Correct far pointer syntax +*/ + +#if defined(__POWERC) || (defined(__TURBOC__) && !defined(__BORLANDC__)) + #define FAR far +#else + #define FAR _far +#endif + +/*---------------------------------------------------------------------------- + Directory search macros and data structures + + DOSFileData MS-DOS file data structure + FIND_FIRST MS-DOS function 0x4E -- find first file matchine spec + FIND_NEXT MS-DOS function 0x4F -- find subsequent files +----------------------------------------------------------------------------*/ + +/* make sure the structure is packed on byte boundary */ + +#if defined(_MSC_VER) || defined(_QC) || defined(__WATCOM__) + #pragma pack(1) +#elif defined(__ZTC__) + #pragma ZTC align 1 +#elif defined(__TURBOC__) && (__TURBOC__ > 0x202) + #pragma option -a- +#endif + +/* use this structure in place of compiler-defined file structure */ + +typedef struct { + char reserved[21]; + char attrib; + unsigned time; + unsigned date; + long size; + char name[13]; + } DOSFileData; + +/* set structure alignment to default */ + +#if defined (_MSC_VER) || defined(_QC) || defined(__WATCOMC__) + #pragma pack() +#elif defined (__ZTC__) + #pragma ZTC align +#elif defined(__TURBOC__) && (__TURBOC__ > 0x202) + #pragma option -a. +#endif + +/* include proper header files and create macros */ + +#if defined (_MSC_VER) || defined(_QC) || defined(__WATCOMC) + #include "direct.h" + #define FIND_FIRST(spec,attr,buf) _dos_findfirst(spec,attr,\ + (struct find_t *)buf) + #define FIND_NEXT(buf) _dos_findnext((struct find_t *)buf) +#elif defined (__TURBOC__) + #include "dir.h" + #define FIND_FIRST(spec,attr,buf) findfirst(spec,(struct ffblk *)buf,attr) + #define FIND_NEXT(buf) findnext((struct ffblk *)buf) +#elif defined (__ZTC__) + #include "dos.h" + #define FIND_FIRST(spec,attr,buf) _dos_findfirst(spec,attr,\ + (struct find_t *)buf) + #define FIND_NEXT(buf) _dos_findnext((struct find_t *)buf) +#endif + +/*---------------------------------------------------------------------------- + I/O Port Macros + + IN_PORT read byte from I/O port + IN_PORTW read word from I/O port + OUT_PORT write byte to I/O port + OUT_PORTW write word to I/O port +----------------------------------------------------------------------------*/ + +#if defined(__TURBOC__) + #include "dos.h" + #define IN_PORT(port) inportb(port) + #define IN_PORTW(port) inport(port) + #define OUT_PORT(port, val) outportb(port, val) + #define OUT_PORTW(port, val) outport(port, val) +#else + #include "conio.h" + + #define IN_PORT(port) inp(port) + #define IN_PORTW(port) inpw(port) + #define OUT_PORT(port, val) outp(port, val) + #define OUT_PORTW(port, val) outpw(port, val) + +/*---------------------------------------------------------------------------- + Borland pseudo register macros + + These macros replace references to Borland's pseudo register + variables and geninterrup() funciton with traditional struct + REGS/int86 references. +----------------------------------------------------------------------------*/ + +#if !defined(__TURBOC__) + #include "dos.h" + + extern union REGS CPURegs; + + #define _AX CPURegs.x.ax + #define _BX CPURegs.x.bx + #define _CX CPURegs.x.cx + #define _DX CPURegs.x.dx + + #define _AH CPURegs.h.ah + #define _AL CPURegs.h.al + #define _BH CPURegs.h.bh + #define _BL CPURegs.h.bl + #define _CH CPURegs.h.ch + #define _CL CPURegs.h.cl + #define _DH CPURegs.h.dh + #define _DL CPURegs.h.dl + + #define geninterrupt(n) int86(n,&CPURegs,&CPURegs); + #define O_DENYALL 0x10 + #define O_DENYWRITE 0x20 + #define O_DENYREAD 0x30 + #define O_DENYNONE 0x40 +#endif + +#endif + +/*---------------------------------------------------------------------------- + Pointer-related macros + + MK_FP creates a far pointer from segment and offset values +----------------------------------------------------------------------------*/ + +#if !defined(MK_FP) + #define MK_FP(seg,off) ((void FAR *)(((long)(seg) << 16)|(unsigned)(off))) +#endif + +#endif diff --git a/reference/C/CONTRIB/SNIP/posix_ls.c b/reference/C/CONTRIB/SNIP/posix_ls.c new file mode 100755 index 0000000..84aa83d --- /dev/null +++ b/reference/C/CONTRIB/SNIP/posix_ls.c @@ -0,0 +1,83 @@ +/* +** POSIX_LS.C - Directory lister using POSIX style processing +** +** Original Copyright 1988-1991 by Bob Stout as part of +** the MicroFirm Function Library (MFL) +** +** This subset version is functionally identical to the +** version originally published by the author in Tech Specialist +** magazine and is hereby donated to the public domain. +*/ + +#include +#include "dirent.h" + +#define SUCCESS 0 + +void dumpdir(char *dirname, char *mask) +{ + DOS_DIR *dirp; + struct DSTRUCT *dstruct; + + dirp = opendir(dirname); + if (!dirp) + { + printf("Opening %s returned NULL\n\n", dirname); + return; + } + printf("Dir %s has %d entries\n", dirname, dirp->dd_size); + do + { + if (NULL != (dstruct = readdir(dirp))) + { + if (SUCCESS == dirmask(dstruct, mask, NULL, FA_ANY, 0)) + printf("%3d - %s\n", dirp->dd_loc, dstruct->NAME); + } + else puts("EOF\n"); + } while (dstruct); + printf("seekdir( -1) returned %p\n", seekdir(dirp, -1, SEEK_SET)); + printf("seekdir(999) returned %p\n", seekdir(dirp, 999, SEEK_SET)); + printf("seekdir(0, SEEK_SET) returned %p\n", dstruct = seekdir(dirp, + 0, SEEK_SET)); + printf("%3d - %s\n", dirp->dd_loc, dstruct->NAME); + printf("seekdir(1, SEEK_SET) returned %p\n", dstruct = seekdir(dirp, + 1, SEEK_SET)); + printf("%3d - %s\n", dirp->dd_loc, dstruct->NAME); + printf("seekdir(4, SEEK_SET) returned %p\n", dstruct = seekdir(dirp, + 4, SEEK_SET)); + printf("%3d - %s\n", dirp->dd_loc, dstruct->NAME); + printf("seekdir(4, SEEK_CUR) returned %p\n", dstruct = seekdir(dirp, + 4, SEEK_CUR)); + printf("%3d - %s\n", dirp->dd_loc, dstruct->NAME); + printf("seekdir(-1, SEEK_CUR) returned %p\n", dstruct = seekdir(dirp, + -1, SEEK_CUR)); + printf("%3d - %s\n", dirp->dd_loc, dstruct->NAME); + printf("seekdir(1, SEEK_CUR) returned %p\n", dstruct = seekdir(dirp, + 1, SEEK_CUR)); + printf("%3d - %s\n", dirp->dd_loc, dstruct->NAME); + printf("seekdir(0, SEEK_END) returned %p\n", dstruct = seekdir(dirp, + 0, SEEK_END)); + printf("%3d - %s\n", dirp->dd_loc, dstruct->NAME); + printf("seekdir(-1, SEEK_END) returned %p\n", dstruct = seekdir(dirp, + -1, SEEK_END)); + printf("%3d - %s\n", dirp->dd_loc, dstruct->NAME); + printf("seekdir(-4, SEEK_END) returned %p\n", dstruct = seekdir(dirp, + -4, SEEK_END)); + printf("%3d - %s\n", dirp->dd_loc, dstruct->NAME); + closedir(dirp); +} + +void main(int argc, char *argv[]) +{ + int i; + char *mask = NULL, *dirname; + + if (1 < argc) + dirname = argv[1]; + else dirname = "."; + + if (2 < argc) + mask = argv[2]; + printf("Calling dumpdir(%s, %s)\n\n", dirname, mask); + dumpdir(dirname, mask); +} diff --git a/reference/C/CONTRIB/SNIP/posixdir.c b/reference/C/CONTRIB/SNIP/posixdir.c new file mode 100755 index 0000000..81f83a2 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/posixdir.c @@ -0,0 +1,276 @@ +/* +** POSIXDIR.C - POSIX-style directory processing +** +** Original Copyright 1988-1991 by Bob Stout as part of +** the MicroFirm Function Library (MFL) +** +** This subset version is functionally identical to the +** version originally published by the author in Tech Specialist +** magazine and is hereby donated to the public domain. +*/ + +#include +#include +#include +#include +#include +#include "dirent.h" + +#define _NDIRS 20 +#define SUCCESS 0 +#define ERROR -1 + +#define LAST_CHAR(s) ((char *)(s))[strlen(s) - 1] + +int DFerr; +DOS_DIR _DIRS[_NDIRS]; /* Initilize DOS_DIR array to zeros */ + +/* +** Convert Unix-style pathnames to DOS-style +*/ + +static char *unix2dos(char *path) +{ + char *p; + + while (NULL != (p = strchr(path, '/'))) + *p = '\\'; + return path; +} + +/****************************************************************/ +/* */ +/* opendir() */ +/* */ +/* Function: Open a directory for reading. */ +/* */ +/* Parameters: 1 - Directory name. May include path spec. */ +/* */ +/* Returns: Pointer to a DOS_DIR typedef'ed structure, similar */ +/* to fopen() returning a FILE pointer. */ +/* */ +/* NULL if error, DFerr set as follows: */ +/* SUCCESS - No error */ +/* ENOENT - Could not locate directory or contents */ +/* ENOTDIR - Not a directory */ +/* ENOMEM - Too many directories already open */ +/* */ +/* Side effects: The dd_size element of the DOS_DIR structure */ +/* will contain a number representing the total */ +/* number of entries in the directory. The */ +/* dd_loc element will be set to zero since */ +/* no elements have, as yet, been read. */ +/* */ +/****************************************************************/ + +DOS_DIR *opendir(char *fname) +{ + int i; + unsigned n = 0; + char nametmp[13], *p; + struct DSTRUCT dstruct; + + for (i = 0; i < _NDIRS; ++i) + { + if (!_DIRS[i].dd_fd) + break; + } + if (_NDIRS <= i) + { + DFerr = ENOMEM; + return NULL; + } + + unix2dos(fname); + if (':' == fname[1] && 1 < strlen(fname)) + p = &fname[2]; + else p = fname; + while ('\\' == LAST_CHAR(p) && 1 < strlen(p)) + LAST_CHAR(p) = '\0'; + + if (strcmp(p, "\\") && strlen(p)) + { + if (NULL == (rfind_1st(fname, FA_ANY, &_DIRS[i].dd_buf))) + { + DFerr = ENOENT; + return NULL; + } + if (!(FA_DIREC & _DIRS[i].dd_buf.ATTRIBUTE)) + { + DFerr = ENOTDIR; + return NULL; + } + } + strcpy(_DIRS[i].dd_dirname, fname); + if (!strlen(p)) + strcat(_DIRS[i].dd_dirname, "."); + if ('\\' != LAST_CHAR(_DIRS[i].dd_dirname)) + strcat(_DIRS[i].dd_dirname, "\\"); + strcat(strupr(_DIRS[i].dd_dirname), "*.*"); + if (NULL == rfind_1st(_DIRS[i].dd_dirname, FA_ANY, &_DIRS[i].dd_buf)) + { + DFerr = ENOENT; + return NULL; + } + memcpy(&dstruct, &_DIRS[i].dd_buf, sizeof(struct DSTRUCT)); + do + { + ++n; + } while (rfind_nxt(&_DIRS[i].dd_buf)); + memcpy(&_DIRS[i].dd_buf, &dstruct, sizeof(struct DSTRUCT)); + _DIRS[i].dd_size = n; + _DIRS[i].dd_loc = 0; + _DIRS[i].dd_fd = i + 1; + DFerr = SUCCESS; + return &_DIRS[i]; +} + +/****************************************************************/ +/* */ +/* closedir() */ +/* */ +/* Function: Close a preeviously opened directory. */ +/* */ +/* Parameters: 1 - DOS_DIR pointer of directory to close. */ +/* */ +/* Returns: SUCCESS or ERROR. */ +/* */ +/****************************************************************/ + +int closedir(DOS_DIR *dirp) +{ + if (0 == dirp->dd_fd || _NDIRS < dirp->dd_fd) + { + DFerr = EBADF; + return ERROR; + } + memset(dirp, 0, sizeof(DOS_DIR)); + return SUCCESS; +} + +/****************************************************************/ +/* */ +/* rewinddir() */ +/* */ +/* Function: Reset an open DOS_DIR to its first entry. */ +/* */ +/* Parameters: 1 - DOS_DIR pointer of directory to rewind. */ +/* */ +/* Returns: SUCCESS or ERROR. */ +/* */ +/****************************************************************/ + +int rewinddir(DOS_DIR *dirp) +{ + if (0 == dirp->dd_fd || _NDIRS < dirp->dd_fd) + { + DFerr = EBADF; + return ERROR; + } + rfind_1st(dirp->dd_dirname, FA_ANY, &(dirp->dd_buf)); + dirp->dd_loc = 0; + return SUCCESS; +} + +/****************************************************************/ +/* */ +/* seekdir() */ +/* */ +/* Function: Point to a selected entry in a DOS_DIR. */ +/* */ +/* Parameters: 1 - DOS_DIR pointer of directory to rewind. */ +/* 2 - Offset of entry to seek */ +/* 3 - Origin of offset */ +/* */ +/* Returns: A DSTRUCT pointer, same as returned by rfind_1st() */ +/* and rfind_nxt(). */ +/* */ +/* NULL if error, DFerr set as follows: */ +/* SUCCESS - No error */ +/* EBADF - Bad file (DOS_DIR) pointer */ +/* EACCES - Illegal origin specification */ +/* EOF - Attempt to seek past end of directory */ +/* */ +/****************************************************************/ + +struct DSTRUCT *seekdir(DOS_DIR *dirp, int offset, int origin) +{ + int i, loc; + + if (0 == dirp->dd_fd || _NDIRS < dirp->dd_fd) + { + DFerr = EBADF; + return NULL; + } + switch (origin) + { + case SEEK_SET: + loc = offset + 1; + break; + case SEEK_CUR: + loc = dirp->dd_loc + offset; + break; + case SEEK_END: + loc = dirp->dd_size + offset; + break; + default: + DFerr = EACCES; + return NULL; + } + + if (loc > (int)dirp->dd_size || 0 >= loc) + { + DFerr = EOF; + return NULL; + } + + rewinddir(dirp); + for (i = 0; i < loc; ++i) + readdir(dirp); + + DFerr = SUCCESS; + return (&(dirp->dd_buf)); +} + +/****************************************************************/ +/* */ +/* readdir() */ +/* */ +/* Function: Reads entries from an open directory. */ +/* */ +/* Parameters: 1 - DOS_DIR pointer of directory to read. */ +/* */ +/* Returns: A DSTRUCT pointer, same as returned by rfind_1st() */ +/* and rfind_nxt(). */ +/* */ +/* NULL if error, DFerr set as follows: */ +/* SUCCESS - No error */ +/* EBADF - Bad file (DOS_DIR) pointer */ +/* EOF - Attempt to read past end of directory */ +/* */ +/* Side effects: The dd_loc element of the DOS_DIR structure */ +/* will contain a number representing which */ +/* element of the directory was returned. It may */ +/* range from 1 to dd_size. */ +/* */ +/****************************************************************/ + +struct DSTRUCT *readdir(DOS_DIR *dirp) +{ + if (0 == dirp->dd_fd || _NDIRS < dirp->dd_fd) + { + DFerr = EBADF; + return NULL; + } + if (0 == dirp->dd_loc || NULL != rfind_nxt(&(dirp->dd_buf))) + { + dirp->dd_loc += 1; + DFerr = SUCCESS; + return (&(dirp->dd_buf)); + } + else + { + DFerr = EOF; + return NULL; + } +} diff --git a/reference/C/CONTRIB/SNIP/pr.c b/reference/C/CONTRIB/SNIP/pr.c new file mode 100755 index 0000000..328a8de --- /dev/null +++ b/reference/C/CONTRIB/SNIP/pr.c @@ -0,0 +1,301 @@ +/* + This program is similar to a program of the same name found on UNIX. + It prints the files named in the command tail with headings + except as modified below. + + usage: pr [-i -ln -on -pname -tn -wn] file1[ file2 ... filen] + where: -i = accept files from stdin + -ln = set lines per page to n + -on = set page offset to n + -pname = output to file + -tn = set tabs to n cols + -wn = set page width to n + + note: the expr 'PAGE(mesg)' found in col 1 will cause a formfeed + and the 'mesg' to be included in the title line on this and + each subsequent page until EOF or another PAGE. +*/ + +#include + +#define TAB_DEFAULT 4 +#define PAGE_LENGTH 60 +#define PAGE_OFFSET 0 +#define PAGE_WIDTH 80 +#define MAX_ARGS 70 +#define MAX_FILES 64 +#define PATH_LENGTH 63 +#define PAGE(head) + +#ifndef TRUE + +#define TRUE 1 +#define FALSE 0 + +#endif + + +int page_length = PAGE_LENGTH; +int page_offset = PAGE_OFFSET; +int page_width = PAGE_WIDTH; + +int tab_width = TAB_DEFAULT; + +char *xargv[ MAX_ARGS ]; +unsigned xargc; + +char filenames [MAX_FILES] [PATH_LENGTH + 1]; + +char *print_name = "PRN:"; + +extern long atoi(); + +char title [80]; +char date [20]; +char time [20]; +int ln, pn; + +PAGE (MAIN) +main(argc, argv) /* copy file to printer */ +int argc; +char *argv []; +{ + FILE *file, *lp; + int fi = 0; + int read_stdin = FALSE; + int pn; + char *cp; + + if (argc < 2) /* No args so tell 'em how it works */ + { + fprintf(stderr, + "usage:\n\npr %s %s\n\n", + "[-i] [-lnn] [-onn] [-p] [-tn] [-wnn]", + "[file1[ file2 ... filen]]"); + fprintf(stderr, + "where: i = read 'stdin' for filenames to print\n"); + fprintf(stderr, + " l = lines-per-page and nn <= 120\n"); + fprintf(stderr, + " o = page offset and nn <= 120\n"); + fprintf(stderr, + " p = print redirection and\n"); + fprintf(stderr, + " = pathname or devicename\n"); + fprintf(stderr, + " t = spaces-per-tab and n <= 8\n"); + fprintf(stderr, + " w = page width and nn <= 160\n\n"); + fprintf(stderr, + "Notes: PAGE() in col 1 of text file\n"); + fprintf(stderr, + " and <title text...> the title you want.\n\n"); + fprintf(stderr, + " C pgms should include the following macro:\n\n"); + fprintf(stderr, + " #define PAGE(title)\n\n"); + fprintf(stderr, + " < and > not required and should not be used\n\n"); + exit(0); + } + + xargc = xargs("pr", argc, argv, xargv, MAX_ARGS); + + for (pn = 0; pn < xargc; pn++) + { + if (*xargv[pn] == '-') + { + cp = xargv[pn] + 1; + switch (tolower(*cp)) + { + case 'i':/* wants help */ + read_stdin = TRUE; + break; + case 'l':/* page length change */ + page_length = (int) atoi(cp + 1); + if ((page_length <= 0) || (page_length > 120)) + page_length = PAGE_LENGTH; + break; + + case 'p':/* direct output to file */ + print_name = cp + 1; + break; + + case 't':/* tab width change */ + tab_width = (int) atoi(cp + 1); + if ((tab_width <= 0) || (tab_width > 8)) + tab_width = TAB_DEFAULT; + break; + + case 'o':/* page offset change */ + page_offset = (int) atoi(cp + 1); + if ((page_offset < 0) || (page_offset > 120)) + page_offset = PAGE_OFFSET; + break; + + case 'w':/* page width change */ + page_width = (int) atoi(cp + 1); + if ((page_width <= 0) || (page_width > 160)) + page_width = PAGE_WIDTH; + break; + + default: + fprintf(stderr, "pr: Invalid option = %s\n", + xargv[pn]); + } + } + else /* must be a path name */ + { + if (fi < MAX_FILES) + strcpy(filenames[fi++], xargv[pn]); + else + { + fprintf(stderr, "pr: " + "Exceeded maximum file capacity\n"); + break; + } + } + } + + if ((lp = fopen(print_name, "w")) == 0) + { + fprintf(stderr, "pr: Unable to open %s as output\n", print_name); + exit(1); + } + + if (read_stdin) + { + for(;;) + { + if (fi == MAX_FILES) + { + fputs("pr: Exceeded maximum file capacity\n", + stderr); + break; + } + cp = gets(filenames [fi], PATH_LENGTH); + if (!cp) + break; + else fi++; + } + } + /* now print each file */ + + for (pn = 0; pn < fi; pn++) + prt(filenames [pn], lp); /* print the file */ +} +PAGE (NEW PAGE) + +new_page (fnp, lp) +char *fnp; +FILE *lp; +{ + if (ln < 3) + return; + ++pn; + if (pn > 1) + fputc('\f', lp); + fprintf(lp, "%s %s %s PAGE %d: %s\n\n", + fnp, date, time, pn, title); + ln = 2; +} + +PAGE (PRINT FILE) +prt (fnp, lp) +char fnp[]; +FILE *lp; +{ + FILE *inp_file; + int i, j, col; + char line [256], *st, *et, *sp; + + inp_file = fopen(fnp, "r"); + if (!inp_file) + { + fprintf(stderr, "pr: unable to open %s\n", fnp); + return; + } + else + fprintf(stderr, "pr: printing %s\n", fnp); + + pn = 0; + ln = 999; + gdates(date); /* get date */ + gtimes(time); /* and time */ + *title = '\0'; + + while (fgets(line, 256, inp_file)) + { + if (strncmp(line, "PAGE", 4) == 0) + { + if (st = index(line, '(')) + { + et = index(line, ')'); + strncpy(title, st + 1, (et) ? et - st - 1 : 160); + } + ln = 999; + } + + if (ln > page_length) + new_page(fnp, lp); + + if (page_offset) + indent(lp); + + for (col = (page_offset) ? page_offset : 1, sp = &line[0]; + *sp; sp++) + { + switch (*sp) + { + case '\t': /* tab character */ + do + { + fputc(' ', lp); + col++; + if (col > page_width) + { + fputc('\n', lp); + col = (page_offset) ? page_offset : 1; + ln++; + if (ln > page_length) + new_page(fnp, lp); + if (page_offset) + indent(lp); + break; + } + } while ((col - 1) % tab_width); + break; + + case '\f': /* form feed character */ + new_page(fnp, lp); + break; + + default: + fputc(*sp, lp); + ++col; + if (col > page_width) + { + fputc('\n', lp); + col = (page_offset) ? page_offset - 1 : 0; + ln++; + if (ln > page_length) + new_page(fnp, lp); + if (page_offset) + indent(lp); + } + } + } /* of line print (for) */ + ++ln; + } /* of while not eof */ + fclose(inp_file); + fputc(014, lp); +} /* of print */ + +indent(lp) +FILE *lp; +{ + int i; + + for(i = 1; i < page_offset; i++) + fputc(' ', lp); +} diff --git a/reference/C/CONTRIB/SNIP/printq.c b/reference/C/CONTRIB/SNIP/printq.c new file mode 100755 index 0000000..c0f4818 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/printq.c @@ -0,0 +1,46 @@ +/* printq.c 12-22-91 Robert Mashlan, Public Domain + + A small program that utilizes the prnspool module, + which is an interface to the DOS program PRINT.COM + +*/ + +#include "prnspool.h" +#include <stdio.h> +#include <string.h> + +int main(int argc, char **argv ) +{ + char far *files; + int i; + int addfiles = 1; + + if (!printspool_installed()) + { + printf("print.com not installed\n"); + return 0; + } + for (i = 1; i < argc; i++) + { + if (stricmp(argv[i],"/T") == 0) + printspool_cancel(); /* cancel all files in queue */ + else if (stricmp(argv[i],"/C") == 0) + addfiles = 0; /* cancel all listed files */ + else if (stricmp(argv[i],"/P") == 0) + addfiles = 1; /* add all listed files */ + else + /* here the specified file should really have the full pathname */ + { + if (addfiles) + printspool_submit(argv[i]); + else printspool_remove(argv[i]); + if (printspool_errno) + puts(printspool_errlist[printspool_errno]); + } + } + printf("files currently in queue:\n"); + for (files = printspool_getqueue(); *files; files += 64) + printf("\t%Fs\n", files); + printspool_endhold(); + return 0; +} diff --git a/reference/C/CONTRIB/SNIP/prnspool.c b/reference/C/CONTRIB/SNIP/prnspool.c new file mode 100755 index 0000000..f842800 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/prnspool.c @@ -0,0 +1,151 @@ +/* prnspool.c 12-22-91 Robert Mashlan, public domain */ +/* DOS print spooler interface functions */ + +#include <stdio.h> +#include <dos.h> +#include "prnspool.h" + +int printspool_errno = 0; + +char *printspool_errlist[] = { + "No error", + "Function Invalid", + "File not found", + "Path not found", + "Too many open files", + "Access denied", + "", + "", + "Queue full", + "Spooler busy", + "", + "", + "Name too long", + "", + "Drive invalid" + }; + +/* returns -1 if printspooler installed */ +/* 0 otherwise */ + +int printspool_installed(void) +{ + union REGS r; + + r.x.ax = 0x0100; + int86(0x2f, &r, &r); + if(r.h.al==0xff) + { + printspool_errno=0; + return -1; + } + else + { + printspool_errno=1; + return 0; + } +} + +/* submits a file name to be printed */ +/* returns error code */ + +int printspool_submit( const char *pathname ) +{ + struct PACKET packet; + union REGS r; + struct SREGS s; + + packet.level = 0; + packet.pathname = (char far *)pathname; + s.ds = FP_SEG(&packet); + r.x.dx = FP_OFF(&packet); + r.x.ax = 0x0101; + int86x(0x2f, &r, &r, &s); + if(!r.x.cflag) + return printspool_errno = 0; + else return printspool_errno = r.x.ax; +} + +/* removes a file from the print queue */ + +int printspool_remove( const char far *fname ) +{ + union REGS r; + struct SREGS s; + + s.ds = FP_SEG(fname); + r.x.dx = FP_OFF(fname); + r.x.ax = 0x0102; + int86x(0x2f, &r, &r, &s); + if(!r.x.cflag) + return printspool_errno = 0; + else return printspool_errno=r.x.ax; +} + +/* cancels all files in the print queue */ + +int printspool_cancel(void) +{ + union REGS r; + + r.x.ax = 0x0103; + int86(0x2f, &r, &r); + if(!r.x.cflag) + return printspool_errno = 0; + else return printspool_errno = r.x.ax; +} + +/* ends hold state after a call to printspool_qetqueue */ +/* or printspool_errorcount */ + +void printspool_endhold(void) +{ + union REGS r; + + r.x.ax = 0x0105; + int86(0x2f, &r, &r); +} + +/* returns a far pointer to the printspooler queue, */ +/* an array of 64 char asciiz strings */ + +char far *printspool_getqueue(void) +{ + char far *result; + union REGS r; + struct SREGS s; + + r.x.ax = 0x0104; + int86x(0x2f, &r, &r, &s); + result = MK_FP(s.ds,r.x.si); + if (!r.x.cflag) + { + printspool_errno = 0; + return result; + } + else + { + printspool_errno = r.x.ax; + return NULL; + } +} + +/* returns the error count from the printspooler */ + +int printspool_errorcount(void) +{ + union REGS r; + + r.x.ax = 0x0104; + int86(0x2f, &r, &r); + if (!r.x.cflag) + { + printspool_errno = 0; + return r.x.dx; /* return the number of errors */ + } + else + { + printspool_errno = r.x.ax; + return r.x.dx; + } +} diff --git a/reference/C/CONTRIB/SNIP/prnspool.h b/reference/C/CONTRIB/SNIP/prnspool.h new file mode 100755 index 0000000..0b1f50c --- /dev/null +++ b/reference/C/CONTRIB/SNIP/prnspool.h @@ -0,0 +1,48 @@ +/* prnspool.h 12-22-91 Robert Mashlan, public domain */ +/* print spooler interface functions header file */ +/* modified by Bob Stout, Nov '93 */ + +#ifdef __TURBOC__ + #define FAR far +#else + #define FAR _far + #if (defined(_MSC_VER) && (_MSC_VER >= 700)) || (defined(__SC__)) + /* Make FP_xxx macros lvalues as in older versions */ + #undef FP_SEG + #undef FP_OFF + #define FP_SEG(fp) ((unsigned)((unsigned long)(fp) >> 16)) + #define FP_OFF(fp) ((unsigned)(fp && 0xffff)) + #endif +#endif + +#ifndef MK_FP + #define MK_FP(seg,offset) \ + ((void _far *)(((unsigned long)(seg)<<16) | (unsigned)(offset))) +#endif + +struct PACKET { + unsigned char level; + char far *pathname; +}; + +extern int printspool_errno; +extern char *printspool_errlist[]; + +int printspool_installed(void); +int printspool_submit( const char *pathname ); +int printspool_remove( const char far *fname ); +int printspool_cancel(void); +char far *printspool_getqueue(void); +void printspool_endhold(void); +int printspool_errorcount(void); + +#define PSENOERR 0x00 +#define PSEINVFNC 0x01 +#define PSENOFILE 0x02 +#define PSENOPATH 0x03 +#define PSEMFILE 0x04 +#define PSEACCES 0x05 +#define PSEQUEFUL 0x08 +#define PSESPLBUSY 0x09 +#define PSENME2LNG 0x0c +#define PSEINVDRV 0x0f diff --git a/reference/C/CONTRIB/SNIP/prtoggle.c b/reference/C/CONTRIB/SNIP/prtoggle.c new file mode 100755 index 0000000..127a1fc --- /dev/null +++ b/reference/C/CONTRIB/SNIP/prtoggle.c @@ -0,0 +1,91 @@ +/* +** prtoggle() +** +** Tee's all standard output to the printer. +** +** Parameters: None +** +** Returns: 0 if operation was successful. +** -1 if stdout or stdin is redirected. +** +** Side effects: Flushes the keyboard buffer +** +** Original Copyright 1988-1991 by Bob Stout as part of +** the MicroFirm Function Library (MFL) +** +** This subset version is functionally identical to the +** version originally published by the author in Tech Specialist +** magazine and is hereby donated to the public domain. +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <conio.h> +#include <io.h> + +#if !defined(__ZTC__) && !defined(__TURBOC__) + #define MK_FP(seg,offset) \ + ((void far *)(((unsigned long)(seg)<<16) | (unsigned)(offset))) + #define peek(s,o) (*((unsigned far *)(MK_FP(s,o)))) + #define poke(s,o,w) (*((unsigned far *)(MK_FP(s,o)))=(w)) +#endif + +#define SUCCESS 0 +#define ERROR -1 + +static unsigned head, tail, start, end; +static int idx = 0; +static unsigned keystack[16][2]; + +int ungetkey(unsigned key) +{ + int count; + +#ifdef __ZTC__ + peek(0x40, 0x1a, &head, sizeof(unsigned)); + peek(0x40, 0x1c, &tail, sizeof(unsigned)); +#else + head = peek(0x40, 0x1a); + tail = peek(0x40, 0x1c); +#endif + count = tail - head; + if (0 > count) + count += (16 * sizeof(unsigned)); + count >>= 1; + + if (15 > count) + { +#ifdef __ZTC__ + peek(0x40, tail, &keystack[idx][0], sizeof(unsigned)); +#else + keystack[idx][0] = peek(0x40, tail); +#endif + keystack[idx][1] = tail; +#ifdef __ZTC__ + poke(0x40, tail, &key, sizeof(unsigned)); +#else + poke(0x40, tail, key); +#endif + tail += sizeof(unsigned); + if (0x3e <= tail) + tail = 0x1e; +#ifdef __ZTC__ + poke(0x40, 0x1c, &tail, sizeof(unsigned)); +#else + poke(0x40, 0x1c, tail); +#endif + return key; + } + return EOF; +} + +int prtoggle(void) +{ + if (!isatty(fileno(stdin)) || !isatty(fileno(stdout))) + return -1; + while (kbhit()) /* Flush the keyboard buffer */ + getch(); + ungetkey('P' - 64); /* Stuff a Ctrl-P into the buffer */ + system(""); /* Let COMMAND.COM do the work */ + return 0; +} diff --git a/reference/C/CONTRIB/SNIP/prtscrn.c b/reference/C/CONTRIB/SNIP/prtscrn.c new file mode 100755 index 0000000..b22bad6 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/prtscrn.c @@ -0,0 +1,53 @@ +/* +** PRTSC.C - Access the BIOS print screen function +** +** public domain demo by Bob Stout +*/ + +#include <dos.h> + +#ifdef __TURBOC__ + #define FAR far +#else + #define FAR _far +#endif + +/* +** Get screen printing status +** +** 0 - Ready +** 1 - Screen printing in process +** 2 - Error occurred last time +*/ + +int PrtScrnStat(void) +{ + return ((int)*((char FAR *)(0x00500000))); +} + +/* +** Print the current screen +*/ + +int PrtScrn(void) +{ + + union REGS regs; /* Dummy for use by int86() */ + + if (1 == PrtScrnStat()) /* Can we print now? */ + return -1; /* Nope, return with error */ + int86(5, ®s, ®s); /* Issue Int 5 */ + return 0; +} + +#ifdef TEST + +#include <stdio.h> + +void main(void) +{ + printf("PrtScrn() returned %d\n", PrtScrn()); + printf("PrtScrnStat() returned %d\n", PrtScrnStat()); +} + +#endif diff --git a/reference/C/CONTRIB/SNIP/prtstat.c b/reference/C/CONTRIB/SNIP/prtstat.c new file mode 100755 index 0000000..e541939 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/prtstat.c @@ -0,0 +1,68 @@ +/* +** PRTSTAT.H - Header file for PRTSTAT.C +*/ + +#ifndef PRTSTAT_H + #define PRTSTAT_H + +struct PrStatus { + unsigned int timeout : 1; + unsigned int unused : 2; + unsigned int IOerror : 1; + unsigned int selected : 1; + unsigned int paperout : 1; + unsigned int ack : 1; + unsigned int notbusy : 1; +}; + +int prtstat(unsigned int); + +#endif + +/*** End of PRTSTAT.H *******************************************************/ + +/* +** PRTSTAT.C - Determine printer status +** +** public domain by Bob Stout +*/ + +#include <dos.h> + +#ifndef PRTSTAT_H + #include "prtstat.h" +#endif + +/* +** prtstat() - Call with printer number (0 = LPT1, 1 = LPT2, 2 = LPT3) +** +** Returns status which can be mapped to a PrStatus struct +*/ + +int prtstat(unsigned int printer_no) +{ + union REGS regs; + + regs.h.ah = 2; + regs.x.dx = printer_no; + int86(0x17, ®s, ®s); + return regs.h.ah; +} + +#ifdef TEST + +#include <stdio.h> + +#define show(x) printf(#x" is %strue (LPT1)\n", mystat.x ? "" : "not "); + +void main(void) +{ + struct PrStatus mystat; + + *((int *)&mystat) = prtstat(0); + show(notbusy); + show(selected); + show(paperout); +} + +#endif diff --git a/reference/C/CONTRIB/SNIP/psplit.c b/reference/C/CONTRIB/SNIP/psplit.c new file mode 100755 index 0000000..a1837b3 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/psplit.c @@ -0,0 +1,110 @@ +/* +** psplit() - Portable replacement for fnsplit(), _splitpath(), etc. +** +** Splits a full DOS pathname into drive, path, file, and extension +** specifications. Works with forward or back slash path separators and +** network file names, e.g. NET:LOONEY/BIN\WUMPUS.COM, Z:\MYDIR.NEW/NAME.EXT +** +** Arguments: 1 - Full pathname to split +** 2 - Buffer for drive +** 3 - Buffer for path +** 4 - Buffer for name +** 5 - Buffer for extension +** +** Returns: Nothing +** +** public domain by Bob Stout +*/ + +#include <stdlib.h> +#include <string.h> + +#define NUL '\0' + +void psplit(char *path, char *drv, char *dir, char *fname, char *ext) +{ + char ch, *ptr, *p; + + /* convert slashes to backslashes for searching */ + + for (ptr = path; *ptr; ++ptr) + { + if ('/' == *ptr) + *ptr = '\\'; + } + + /* look for drive spec */ + + if (NULL != (ptr = strchr(path, ':'))) + { + ++ptr; + if (drv) + { + strncpy(drv, path, ptr - path); + drv[ptr - path] = NUL; + } + path = ptr; + } + else if (drv) + *drv = NUL; + + /* find rightmost backslash or leftmost colon */ + + if (NULL == (ptr = strrchr(path, '\\'))) + ptr = (strchr(path, ':')); + + if (!ptr) + { + ptr = path; /* obviously, no path */ + if (dir) + *dir = NUL; + } + else + { + ++ptr; /* skip the delimiter */ + if (dir) + { + ch = *ptr; + *ptr = NUL; + strcpy(dir, path); + *ptr = ch; + } + } + + if (NULL == (p = strrchr(ptr, '.'))) + { + if (fname) + strcpy(fname, ptr); + if (ext) + *ext = NUL; + } + else + { + *p = NUL; + if (fname) + strcpy(fname, ptr); + *p = '.'; + if (ext) + strcpy(ext, p); + } +} + +#ifdef TEST + +#include <stdio.h> + +int main(int argc, char *argv[]) +{ + char drive[10], pathname[FILENAME_MAX], fname[9], ext[5]; + + while (--argc) + { + psplit(*++argv, drive, pathname, fname, ext); + printf("psplit(%s) returns:\n drive = %s\n path = %s\n" + " name = %s\n ext = %s\n", + *argv, drive, pathname, fname, ext); + } + return EXIT_SUCCESS; +} + +#endif diff --git a/reference/C/CONTRIB/SNIP/ptr_help.txt b/reference/C/CONTRIB/SNIP/ptr_help.txt new file mode 100755 index 0000000..eff6bff --- /dev/null +++ b/reference/C/CONTRIB/SNIP/ptr_help.txt @@ -0,0 +1,1117 @@ + UNDERSTANDING POINTERS (for beginners) + by Ted Jensen + Version 0.0 + This material is hereby placed in the public domain. + September 5, 1993 + + TABLE OF CONTENTS + + INTRODUCTION; + + CHAPTER 1: What is a pointer? + + CHAPTER 2: Pointer types and Arrays + + CHAPTER 3: Pointers and Strings + + CHAPTER 4: More on Strings + + CHAPTER 5: Pointers and Structures + + CHAPTER 6: Some more on Strings, and Arrays of Strings + + EPILOG: + +================================================================== + +INTRODUCTION: + + Over a period of several years of monitoring various +telecommunication conferences on C I have noticed that one of the +most difficult problems for beginners was the understanding of +pointers. After writing dozens of short messages in attempts to +clear up various fuzzy aspects of dealing with pointers, I set up +a series of messages arranged in "chapters" which I could draw +from or email to various individuals who appeared to need help in +this area. + + Recently, I posted all of this material in the FidoNet CECHO +conference. It received such a good acceptance, I decided to +clean it up a little and submit it for inclusion in Bob Stout's +SNIPPETS file. + + It is my hope that I can find the time to expand on this text +in the future. To that end, I am hoping that those who read this +and find where it is lacking, or in error, or unclear, would +notify me of same so the next version, should there be one, I can +correct these deficiencys. + + It is impossible to acknowledge all those whose messages on +pointers in various nets contributed to my knowledge in this +area. So, I will just say Thanks to All. + + I frequent the CECHO on FidoNet via RBBSNet and can be +contacted via the echo itself or by email at: + + RBBSNet address 8:916/1. + +I can also be reached via + +Internet email at ted.jensen@spacebbs.com + +Or Ted Jensen + P.O. Box 324 + Redwood City, CA 94064 + +================================================================== +CHAPTER 1: What is a pointer? + + One of the things beginners in C find most difficult to +understand is the concept of pointers. The purpose of this +document is to provide an introduction to pointers and their use +to these beginners. + + I have found that often the main reason beginners have a +problem with pointers is that they have a weak or minimal feeling +for variables, (as they are used in C). Thus we start with a +discussion of C variables in general. + + A variable in a program is something with a name, the value +of which can vary. The way the compiler and linker handles this +is that it assigns a specific block of memory within the computer +to hold the value of that variable. The size of that block +depends on the range over which the variable is allowed to vary. +For example, on PC's the size of an integer variable is 2 bytes, +and that of a long integer is 4 bytes. In C the size of a +variable type such as an integer need not be the same on all +types of machines. + + When we declare a variable we inform the compiler of two +things, the name of the variable and the type of the variable. +For example, we declare a variable of type integer with the name +k by writing: + + int k; + + On seeing the "int" part of this statement the compiler sets +aside 2 bytes (on a PC) of memory to hold the value of the +integer. It also sets up a symbol table. And in that table it +adds the symbol k and the address in memory where those 2 bytes +were set aside. + + Thus, later if we write: + + k = 2; + +at run time we expect that the value 2 will be placed in that +memory location reserved for the storage of the value of k. + + In a sense there are two "values" associated with k, one +being the value of the integer stored there (2 in the above +example) and the other being the "value" of the memory location +where it is stored, i.e. the address of k. Some texts refer to +these two values with the nomenclature rvalue (right value, +pronounced "are value") and lvalue (left value, pronunced "el +value") respectively. + + The lvalue is the value permitted on the left side of the +assignment operator '=' (i.e. the address where the result of +evaluation of the right side ends up). The rvalue is that which +is on the right side of the assignment statment, the '2' above. +Note that rvalues cannot be used on the left side of the +assignment statement. Thus: 2 = k; is illegal. + + Okay, now consider: + + int j, k; + k = 2; + j = 7; <-- line 1 + k = j; <-- line 2 + + In the above, the compiler interprets the j in line 1 as the +address of the variable j (its lvalue) and creates code to copy +the value 7 to that address. In line 2, however, the j is +interpreted as its rvalue (since it is on the right hand side of +the assignment operator '='). That is, here the j refers to the +value _stored_ at the memory location set aside for j, in this +case 7. So, the 7 is copied to the address designated by the +lvalue of k. + + In all of these examples, we are using 2 byte integers so all +copying of rvalues from one storage location to the other is done +by copying 2 bytes. Had we been using long integers, we would be +copying 4 bytes. + + Now, let's say that we have a reason for wanting a variable +designed to hold an lvalue (an address). The size required to +hold such a value depends on the system. On older desk top +computers with 64K of memory total, the address of any point in +memory can be contained in 2 bytes. Computers with more memory +would require more bytes to hold an address. Some computers, +such as the IBM PC might require special handling to hold a +segment and offset under certain circumstances. The actual size +required is not too important so long as we have a way of +informing the compiler that what we want to store is an address. + + Such a variable is called a "pointer variable" (for reasons +which will hopefully become clearer a little later). In C when +we define a pointer variable we do so by preceding its name with +an asterisk. In C we also give our pointer a type which, in this +case, refers to the type of data stored at the address we will be +storing in our pointer. For example, consider the variable +definition: + + int *ptr; + + ptr is the _name_ of our variable (just as 'k' was the name +of our integer variable). The '*' informs the compiler that we +want a pointer variable, i.e. to set aside however many bytes is +required to store an address in memory. The "int" says that we +intend to use our pointer variable to store the address of an +integer. Such a pointer is said to "point to" an integer. Note, +however, that when we wrote "int k;" we did not give k a value. +If this definiton was made outside of any function many compilers +will initialize it to zero. Simlarly, ptr has no value, that is +we haven't stored an address in it in the above definition. In +this case, again if the definition is outside of any function, it +is intialized to a value #defined by your compiler as NULL. It +is called a NULL pointer. While in most cases NULL is #defined +as zero, it need not be. That is, different compilers handle +this differently. Also note that while zero is an integer, NULL +need not be. + + But, back to using our new variable ptr. Suppose now that we +want to store in ptr the address of our integer variable k. To +do this we use the unary '&' operator and write: + + ptr = &k; + + What the '&' operator does is retrieve the lvalue (address) +of k, even though k is on the right hand side of the assignment +operator '=', and copies that to the contents of our pointer ptr. +Now, ptr is said to "point to" k. Bear with us now, there is +only one more operator we need to discuss. + + The "dereferencing operator" is the asterisk and it is used +as follows: + + *ptr = 7; + +will copy 7 to the address pointed to by ptr. Thus if ptr +"points to" (contains the address of) k, the above statement will +set the value of k to 7. That is, when we use the '*' this way +we are refering to the value of that which ptr is pointing +at, not the value of the pointer itself. + + Similarly, we could write: + + printf("%d\n",*ptr); + +to print to the screen the integer value stored at the address +pointed to by "ptr". + + One way to see how all this stuff fits together would be to +run the following program and then review the code and the output +carefully. + +------------------------------------------------- +#include <stdio.h> + +int j, k; +int *ptr; + + +int main(void) +{ + j = 1; + k = 2; + ptr = &k; + printf("\n"); + printf("j has the value %d and is stored at %p\n",j,&j); + printf("k has the value %d and is stored at %p\n",k,&k); + printf("ptr has the value %p and is stored at %p\n",ptr,&ptr); + printf("The value of the integer pointed to by ptr is %d\n", + *ptr); + return 0; +} +--------------------------------------- +To review: + + A variable is defined by giving it a type and a name (e.g. + int k;) + + A pointer variable is defined by giving it a type and a name + (e.g. int *ptr) where the asterisk tells the compiler that + the variable named ptr is a pointer variable and the type + tells the compiler what type the pointer is to point to + (integer in this case). + + Once a variable is defined, we can get its address by + preceding its name with the unary '&' operator, as in &k. + + We can "dereference" a pointer, i.e. refer to the value of + that which it points to, by using the unary '*' operator as + in *ptr. + + An "lvalue" of a variable is the value of its address, i.e. + where it is stored in memory. The "rvalue" of a variable is + the value stored in that variable (at that address). + +================================================================== +CHAPTER 2: Pointer types and Arrays + + Okay, let's move on. Let us consider why we need to identify +the "type" of variable that a pointer points to, as in: + + int *ptr; + + One reason for doing this is so that later, once ptr "points +to" something, if we write: + + *ptr = 2; + +the compiler will know how many bytes to copy into that memory +location pointed to by ptr. If ptr was defined as pointing to an +integer, 2 bytes would be copied, if a long, 4 bytes would be +copied. Similarly for floats and doubles the appropriate number +will be copied. But, defining the type that the pointer points +to permits a number of other interesting ways a compiler can +interpret code. For example, consider a block in memory +consisting if ten integers in a row. That is, 20 bytes of memory +are set aside to hold 10 integer. + + Now, let's say we point our integer pointer ptr at the first +of these integers. Furthermore lets say that integer is located +at memory location 100 (decimal). What happens when we write: + + ptr + 1; + + Because the compiler "knows" this is a pointer (i.e. its +value is an address) and that it points to an integer (its +current address, 100, is the address of an integer), it adds 2 to +ptr instead of 1, so the pointer "points to" the _next_ +_integer_, at memory location 102. Similarly, were the ptr +defined as a pointer to a long, it would add 4 to it instead of +1. The same goes for other data types such as floats, doubles, +or even user defined data types such as structures. + + Similarly, since ++ptr and ptr++ are both equivalent to +ptr + 1 (though the point in the program when ptr is incremented +may be different), incrementing a pointer using the unary ++ +operator, either pre- or post-, increments the address it stores +by the amount sizeof(type) (i.e. 2 for an integer, 4 for a long, +etc.). + + Since a block of 10 integers located contiguously in memory +is, by definition, an array of integers, this brings up an +interesting relationship between arrays and pointers. + + Consider the following: + + int my_array[] = {1,23,17,4,-5,100}; + + Here we have an array containing 6 integers. We refer to +each of these integers by means of a subscript to my_array, i.e. +using my_array[0] through my_array[5]. But, we could +alternatively access them via a pointer as follows: + + int *ptr; + + ptr = &my_array[0]; /* point our pointer at the first + integer in our array */ + + And then we could print out our array either using the array +notation or by dereferencing our pointer. The following code +illustrates this: +------------------------------------------------------ +#include <stdio.h> + +int my_array[] = {1,23,17,4,-5,100}; +int *ptr; + +int main(void) +{ + int i; + ptr = &my_array[0]; /* point our pointer to the array */ + printf("\n\n"); + for(i = 0; i < 6; i++) + { + printf("my_array[%d] = %d ",i,my_array[i]); /*<-- A */ + printf("ptr + %d = %d\n",i, *(ptr + i)); /*<-- B */ + } + return 0; +} +---------------------------------------------------- + Compile and run the above program and carefully note lines A +and B and that the program prints out the same values in either +case. Also note how we dereferenced our pointer in line B, i.e. +we first added i to it and then dereferenced the the new pointer. +Change line B to read: + + printf("ptr + %d = %d\n",i, *ptr++); + +and run it again... then change it to: + + printf("ptr + %d = %d\n",i, *(++ptr)); + +and try once more. Each time try and predict the outcome and +carefully look at the actual outcome. + + In C, the standard states that wherever we might use +&var_name[0] we can replace that with var_name, thus in our code +where we wrote: + + ptr = &my_array[0]; + + we can write: + + ptr = my_array; to achieve the same result. + + This leads many texts to state that the name of an array is a +pointer. While this is true, I prefer to mentally think "the +name of the array is a _constant_ pointer". Many beginners +(including myself when I was learning) forget that _constant_ +qualifier. In my opinon this leads to some confusion. For +example, while we can write ptr = my_array; we cannot write + + my_array = ptr; + + The reason is that the while ptr is a variable, my_array is a +constant. That is, the location at which the first element of +my_array will be stored cannot be changed once my_array[] has +been declared. + +Modify the example program above by changing + + ptr = &my_array[0]; to ptr = my_array; + +and run it again to verify the results are identical. + + Now, let's delve a little further into the difference between +the names "ptr" and "my_array" as used above. We said that +my_array is a constant pointer. What do we mean by that? Well, +to understand the term "constant" in this sense, let's go back to +our definition of the term "variable". When we define a variable +we set aside a spot in memory to hold the value of the +appropriate type. Once that is done the name of the variable can +be interpreted in one of two ways. When used on the left side of +the assignment operator, the compiler interprets it as the memory +location to which to move that which lies on the right side of +the assignment operator. But, when used on the right side of the +assignment operator, the name of a variable is interpreted to +mean the contents stored at that memory address set aside to hold +the value of that variable. + + With that in mind, let's now consider the simplest of +constants, as in: + + int i, k; + i = 2; + + Here, while "i" is a variable and then occupies space in the +data portion of memory, "2" is a constant and, as such, instead +of setting aside memory in the data segment, it is imbedded +directly in the code segment of memory. That is, while writing +something like k = i; tells the compiler to create code which at +run time will look at memory location &i to determine the value +to be moved to k, code created by i = 2; simply puts the '2' in +the code and there is no referencing of the data segment. + + Similarly, in the above, since "my_array" is a constant, once +the compiler establishes where the array itself is to be stored, +it "knows" the address of my_array[0] and on seeing: + + ptr = my_array; + +it simply uses this address as a constant in the code segment and +there is no referencing of the data segment beyond that. + + Well, that's a lot of technical stuff to digest and I don't +expect a beginner to understand all of it on first reading. With +time and experimentation you will want to come back and re-read +the first 2 chapters. But for now, let's move on to the +relationship between pointers, character arrays, and strings. + +================================================================== +CHAPTER 3: Pointers and Strings + + The study of strings is useful to further tie in the +relationship between pointers and arrays. It also makes it easy +to illustrate how some of the standard C string functions can be +implemented. Finally it illustrates how and when pointers can and +should be passed to functions. + + In C, strings are arrays of characters. This is not +necessarily true in other languages. In Pascal or (most versions +of) Basic, strings are treated differently from arrays. To start +off our discussion we will write some code which, while preferred +for illustrative purposes, you would probably never write in an +actual program. Consider, for example: + + char my_string[40]; + + my_string[0] = 'T'; + my_string[1] = 'e'; + my_string[2] = 'd': + my_string[3] = '\0'; + + While one would never build a string like this, the end +result is a string in that it is an array of characters +_terminated_with_a_nul_character_. By definition, in C, a string +is an array of characters terminated with the nul character. Note +that "nul" is _not_ the same as "NULL". The nul refers to a zero +as is defined by the escape sequence '\0'. That is it occupies +one byte of memory. The NULL, on the other hand, is the value of +an uninitialized pointer and pointers require more than one byte +of storage. NULL is #defined in a header file in your C +compiler, nul may not be #defined at all. + + Since writing the above code would be very time consuming, C +permits two alternate ways of achieving the same thing. First, +one might write: + + char my_string[40] = {'T', 'e', 'd', '\0',}; + + But this also takes more typing than is convenient. So, C +permits: + + char my_string[40] = "Ted"; + + When the double quotes are used, instead of the single quotes +as was done in the previous examples, the nul character ( '\0' ) +is automatically appended to the end of the string. + + In all of the above cases, the same thing happens. The +compiler sets aside an contiguous block of memory 40 bytes long +to hold characters and initialized it such that the first 4 +characters are Ted\0. + + Now, consider the following program: + +------------------program 3.1------------------------------------- +#include <stdio.h> + +char strA[80] = "A string to be used for demonstration purposes"; +char strB[80]; + +int main(void) +{ + char *pA; /* a pointer to type character */ + char *pB; /* another pointer to type character */ + puts(strA); /* show string A */ + pA = strA; /* point pA at string A */ + puts(pA); /* show what pA is pointing to */ + pB = strB; /* point pB at string B */ + putchar('\n'); /* move down one line on the screen */ + while(*pA != '\0') /* line A (see text) */ + { + *pB++ = *pA++; /* line B (see text) */ + } + *pB = '\0'; /* line C (see text) */ + puts(strB); /* show strB on screen */ + return 0; +} +--------- end program 3.1 ------------------------------------- + + In the above we start out by defining two character arrays of +80 characters each. Since these are globally defined, they are +initialized to all '\0's first. Then, strA has the first 42 +characters initialized to the string in quotes. + + Now, moving into the code, we define two character pointers +and show the string on the screen. We then "point" the ponter pA +at strA. That is, by means of the assignment statement we copy +the address of strA[0] into our variable pA. We now use puts() +to show that which is pointed to by pA on the screen. Consider +here that the function prototype for puts() is: + + int puts(const char *s); + + For the moment, ignore the "const". The parameter passed to +puts is a pointer, that is the _value_ of a pointer (since all +parameters in C are passed by value), and the value of a pointer +is the address to which it points, or, simply, an address. Thus +when we write: + + puts(strA); as we have seen, we are passing the + +address of strA[0]. Similarly, when we write: + + puts(pA); we are passing the same address, since + +we have set pA = strA; + + Given that, follow the code down to the while() statement on +line A. Line A states: + + While the character pointed to by pA (i.e. *pA) is not a nul +character (i.e. the terminating '\0'), do the following: + + line B states: copy the character pointed to by pA to the +space pointed to by pB, then increment pA so it points to the +next character and pB so it points to the next space. + + Note that when we have copied the last character, pA now +points to the terminating nul character and the loop ends. +However, we have not copied the nul character. And, by +definition a string in C _must_ be nul terminated. So, we add +the nul character with line C. + + It is very educational to run this program with your debugger +while watching strA, strB, pA and pB and single stepping through +the program. It is even more educational if instead of simply +defining strB[] as has been done above, initialize it also with +something like: + + strB[80] = "12345678901234567890123456789012345678901234567890" + +where the number of digits used is greater than the length of +strA and then repeat the single stepping procedure while watching +the above variables. Give these things a try! + + Of course, what the above program illustrates is a simple way +of copying a string. After playing with the above until you have +a good understanding of what is happening, we can proceed to +creating our own replacement for the standard strcpy() that comes +with C. It might look like: + + char *my_strcpy(char *destination, char *source) + { + char *p = destination + while (*source != '\0') + { + *p++ = *source++; + } + *p = '\0'; + return destination. + } + + In this case, I have followed the practice used in the +standard routine of returning a pointer to the destination. + + Again, the function is designed to accept the values of two +character pointers, i.e. addresses, and thus in the previous +program we could write: + +int main(void) +{ + my_strcpy(strB, strA); + puts(strB); +} + + I have deviated slightly from the form used in standard C +which would have the prototype: + + char *my_strcpy(char *destination, const char *source); + + Here the "const" modifier is used to assure the user that the +function will not modify the contents pointed to by the source +pointer. You can prove this by modifying the function above, and +its prototype, to include the "const" modifier as shown. Then, +within the function you can add a statement which attempts to +change the contents of that which is pointed to by source, such +as: + + *source = 'X'; + +which would normally change the first character of the string to +an X. The const modifier should cause your compiler to catch +this as an error. Try it and see. + + Now, let's consider some of the things the above examples +have shown us. First off, consider the fact that *ptr++ is to be +interpreted as returning the value pointed to by ptr and then +incrementing the pointer value. On the other hand, note that +this has to do with the precedence of the operators. Were we to +write (*ptr)++ we would increment, not the pointer, but that +which the pointer points to! i.e. if used on the first character +of the above example string the 'T' would be incremented to a +'U'. You can write some simple example code to illustrate this. + + Recall again that a string is nothing more than an array +of characters. What we have done above is deal with copying +an array. It happens to be an array of characters but the +technique could be applied to an array of integers, doubles, +etc. In those cases, however, we would not be dealing with +strings and hence the end of the array would not be +_automatically_ marked with a special value like the nul +character. We could implement a version that relied on a +special value to identify the end. For example, we could +copy an array of postive integers by marking the end with a +negative integer. On the other hand, it is more usual that +when we write a function to copy an array of items other +than strings we pass the function the number of items to be +copied as well as the address of the array, e.g. something +like the following prototype might indicate: + + void int_copy(int *ptrA, int *ptrB, int nbr); + +where nbr is the number of integers to be copied. You might want +to play with this idea and create an array of integers and see if +you can write the function int_copy() and make it work. + + Note that this permits using functions to manipulate very +large arrays. For example, if we have an array of 5000 integers +that we want to manipulate with a function, we need only pass to +that function the address of the array (and any auxiliary +information such as nbr above, depending on what we are doing). +The array itself does _not_ get passed, i.e. the whole array is +not copied and put on the stack before calling the function, only +its address is sent. + + Note that this is different from passing, say an integer, to +a function. When we pass an integer we make a copy of the +integer, i.e. get its value and put it on the stack. Within the +function any manipulation of the value passed can in no way +effect the original integer. But, with arrays and pointers we +can pass the address of the variable and hence manipulate the +values of of the original variables. + +================================================================== +CHAPTER 4: More on Strings + + Well, we have progressed quite aways in a short time! Let's +back up a little and look at what was done in Chapter 3 on +copying of strings but in a different light. Consider the +following function: + + char *my_strcpy(char dest[], char source[]) + { + int i = 0; + + while (source[i] != '\0') + { + dest[i] = source[i]; + i++; + } + dest[i] = '\0'; + return dest; + } + + Recall that strings are arrays of characters. Here we have +chosen to use array notation instead of pointer notation to do +the actual copying. The results are the same, i.e. the string +gets copied using this notation just as accurately as it did +before. This raises some interesting points which we will +discuss. + + Since parameters are passed by value, in both the passing of +a character pointer or the name of the array as above, what +actually gets passed is the address of the first element of each +array. Thus, the numerical value of the parameter passed is the +same whether we use a character pointer or an array name as a +parameter. This would tend to imply that somehow: + + source[i] is the same as *(p+i); + +In fact, this is true, i.e wherever one writes a[i] it can be +replaced with *(a + i) without any problems. In fact, the +compiler will create the same code in either case. Now, looking +at this last expression, part of it.. (a + i) is a simple +addition using the + operator and the rules of c state that such +an expression is commutative. That is (a + i) is identical to +(i + a). Thus we could write *(i + a) just as easily as +*(a + i). + + But *(i + a) could have come from i[a] ! From all of this +comes the curious truth that if: + + char a[20]; + int i; + + writing a[3] = 'x'; is the same as writing + + 3[a] = 'x'; + + Try it! Set up an array of characters, integers or longs, +etc. and assigned the 3rd or 4th element a value using the +conventional approach and then print out that value to be sure +you have that working. Then reverse the array notation as I have +done above. A good compiler will not balk and the results will +be identical. A curiosity... nothing more! + + Now, looking at our function above, when we write: + + dest[i] = source[i]; + + this gets interpreted by C to read: + + *(dest + i) = *(source + i); + + But, this takes 2 additions for each value taken on by i. +Additions, generally speaking, take more time than +incrementations (such as those done using the ++ operator as in +i++). This may not be true in modern optimizing compilers, but +one can never be sure. Thus, the pointer version may be a bit +faster than the array version. + + Another way to speed up the pointer version would be to +change: + + while (*source != '\0') to simply while (*source) + +since the value within the parenthesis will go to zero (FALSE) at +the same time in either case. + + At this point you might want to experiment a bit with writing +some of your own programs using pointers. Manipulating strings +is a good place to experiment. You might want to write your own +versions of such standard functions as: + + strlen(); + strcat(); + strchr(); + +and any others you might have on your system. + + We will come back to strings and their manipulation through +pointers in a future chapter. For now, let's move on and discuss +structures for a bit. + +================================================================== +CHAPTER 5: Pointers and Structures + + As you may know, we can declare the form of a block of data +containing different data types by means of a structure +declaration. For example, a personnel file might contain +structures which look something like: + + struct tag{ + char lname[20]; /* last name */ + char fname[20]; /* first name */ + int age; /* age */ + float rate; /* e.g. 12.75 per hour */ + }; + + Let's say we have an bunch of these structures in a disk file +and we want to read each one out and print out the first and last +name of each one so that we can have a list of the people in our +files. The remaining information will not be printed out. We +will want to do this printing with a function call and pass to +that function a pointer to the structure at hand. For +demonstration purposes I will use only one structure for now. But +realize the goal is the writing of the function, not the reading +of the file which, presumably, we know how to do. + + For review, recall that we can access structure members with +the dot operator as in: + +--------------- program 5.1 ------------------ +#include <stdio.h> +#include <string.h> + +struct tag{ + char lname[20]; /* last name */ + char fname[20]; /* first name */ + int age; /* age */ + float rate; /* e.g. 12.75 per hour */ + }; + +struct tag my_struct; /* declare the structure m_struct */ + +int main(void) +{ + strcpy(my_struct.lname,"Jensen"); + strcpy(my_struct.fname,"Ted"); + printf("\n%s ",my_struct.fname); + printf("%s\n",my_struct.lname); + return 0; +} +-------------- end of program 5.1 -------------- + + Now, this particular structure is rather small compared to +many used in C programs. To the above we might want to add: + + date_of_hire; + date_of_last_raise; + last_percent_increase; + emergency_phone; + medical_plan; + Social_S_Nbr; + etc..... + + Now, if we have a large number of employees, what we want to +do manipulate the data in these structures by means of functions. +For example we might want a function print out the name of any +structure passed to it. However, in the original C (Kernighan & +Ritchie) it was not possible to pass a structure, only a pointer +to a structure could be passed. In ANSI C, it is now permissible +to pass the complete structure. But, since our goal here is to +learn more about pointers, we won't pursue that. + + Anyway, if we pass the whole structure it means there must be +enough room on the stack to hold it. With large structures this +could prove to be a problem. However, passing a pointer uses a +minimum amount of stack space. + + In any case, since this is a discussion of pointers, we will +discuss how we go about passing a pointer to a structure and then +using it within the function. + + Consider the case described, i.e. we want a function that +will accept as a parameter a pointer to a structure and from +within that function we want to access members of the structure. +For example we want to print out the name of the employee in our +example structure. + + Okay, so we know that our pointer is going to point to a +structure declared using struct tag. We define such a pointer +with the definition: + + struct tag *st_ptr; + +and we point it to our example structure with: + + st_ptr = &my_struct; + + Now, we can access a given member by de-referencing the +pointer. But, how do we de-reference the pointer to a structure? +Well, consider the fact that we might want to use the pointer to +set the age of the employee. We would write: + + (*st_ptr).age = 63; + + Look at this carefully. It says, replace that within the +parenthesis with that which st_ptr points to, which is the +structure my_struct. Thus, this breaks down to the same as +my_struct.age. + + However, this is a fairly often used expression and the +designers of C have created an alternate syntax with the same +meaning which is: + + st_ptr->age = 63; + + With that in mind, look at the following program: + +------------ program 5.2 -------------- + +#include <stdio.h> +#include <string.h> + +struct tag{ /* the structure type */ + char lname[20]; /* last name */ + char fname[20]; /* first name */ + int age; /* age */ + float rate; /* e.g. 12.75 per hour */ + }; + +struct tag my_struct; /* define the structure */ + +void show_name(struct tag *p); /* function prototype */ + +int main(void) +{ + struct tag *st_ptr; /* a pointer to a structure */ + st_ptr = &my_struct; /* point the pointer to my_struct */ + strcpy(my_struct.lname,"Jensen"); + strcpy(my_struct.fname,"Ted"); + printf("\n%s ",my_struct.fname); + printf("%s\n",my_struct.lname); + my_struct.age = 63; + show_name(st_ptr); /* pass the pointer */ + return 0; +} + + +void show_name(struct tag *p) +{ + printf("\n%s ", p->fname); /* p points to a structure */ + printf("%s ", p->lname); + printf("%d\n", p->age); +} +-------------------- end of program 5.2 ---------------- + + Again, this is a lot of information to absorb at one time. +The reader should compile and run the various code snippets and +using a debugger monitor things like my_struct and p while single +stepping through the main and following the code down into the +function to see what is happening. + +================================================================== +CHAPTER 6: Some more on Strings, and Arrays of Strings + + Well, let's go back to strings for a bit. In the following +all assignments are to be understood as being global, i.e. made +outside of any function, including main. + + We pointed out in an earlier chapter that we could write: + + char my_string[40] = "Ted"; + +which would allocate space for a 40 byte array and put the string +in the first 4 bytes (three for the characters in the quotes and +a 4th to handle the terminating '\0'. + + Actually, if all we wanted to do was store the name "Ted" we +could write: + + char my_name[] = "Ted"; + +and the compiler would count the characters, leave room for the +nul character and store the total of the four characters in memory +the location of which would be returned by the array name, in this +case my_string. + + In some code, instead of the above, you might see: + + char *my_name = "Ted"; + +which is an alternate approach. Is there a difference between +these? The answer is.. yes. Using the array notation 4 bytes of +storage in the static memory block are taken up, one for each +character and one for the nul character. But, in the pointer +notation the same 4 bytes required, _plus_ N bytes to store the +pointer variable my_name (where N depends on the system but is +usually a minimum of 2 bytes and can be 4 or more). + + In the array notation, my_name is a constant (not a +variable). In the pointer notation my_name is a variable. As to +which is the _better_ method, that depends on what you are going +to do within the rest of the program. + + Let's now go one step further and consider what happens if +each of these definitions are done within a function as opposed +to globally outside the bounds of any function. + +void my_function_A(char *ptr) +{ + char a[] = "ABCDE"; + . + . +} + +void my_function_B(char *ptr) +{ + char *cp = "ABCDE"; + . + . +} + + Here we are dealing with automatic variables in both cases. +In my_function_A the automatic variable is the character array +a[]. In my_function_B it is the pointer cp. While C is designed +in such a way that a stack is not required on those processors +which don't use them, my particular processor (80286) has a +stack. I wrote a simple program incorporating functions similar +to those above and found that in my_function_A the 5 characters +in the string were all stored on the stack. On the other hand, +in my_function_B, the 5 characters were stored in the data space +and the pointer was stored on the stack. + + By making a[] static I could force the compiler to place the +5 characters in the data space as opposed to the stack. I did +this exercise to point out just one more difference between +dealing with arrays and dealing with pointers. By the way, array +initialization of automatic variables as I have done in +my_function_A was illegal in the older K&R C and only "came of +age" in the newer ANSI C. A fact that may be important when one +is considering portabilty and backwards compatability. + + As long as we are discussing the relationship/differences +between pointers and arrays, let's move on to multi-dimensional +arrays. Consider, for example the array: + + char multi[5][10]; + + Just what does this mean? Well, let's consider it in the +following light. + + char multi[5][10]; + ^^^^^^^^^^^^^ + + If we take the first, underlined, part above and consider it +to be a variable in its own right, we have an array of 10 +characters with the "name" multi[5]. But this name, in itself, +implies an array of 5 somethings. In fact, it means an array of +five 10 character arrays. Hence we have an array of arrays. In +memory we might think of this as looking like: + + multi[0] = "0123456789" + multi[1] = "abcdefghij" + multi[2] = "ABCDEFGHIJ" + multi[3] = "9876543210" + multi[4] = "JIHGFEDCBA" + +with individual elements being, for example: + + multi[0][3] = '3' + multi[1][7] = 'h' + multi[4][0] = 'J' + + Since arrays are to be contiguous, our actual memory block +for the above should look like: + + "0123456789abcdefghijABCDEFGHIJ9876543210JIHGFEDCBA" + + Now, the compiler knows how many columns are present in the +array so it can interpret multi + 1 as the address of the 'a' in +the 2nd row above. That is, it adds 10, the number of columns, +to get this location. If we were dealing with integers and an +array with the same dimension the compiler would add +10*sizeof(int) which, on my machine, would be 20. Thus, the +address of the "9" in the 4th row above would be &multi[3][0] or +*(multi + 3) in pointer notation. To get to the content of the +2nd element in row 3 we add 1 to this address and dereference the +result as in + + *(*(multi + 3) + 1) + + With a little thought we can see that: + + *(*(multi + row) + col) and + multi[row][col] yield the same results. + + The following program illustrates this using integer arrays +instead of character arrays. + +------------------- program 6.1 ---------------------- +#include <stdio.h> + +#define ROWS 5 +#define COLS 10 + +int multi[ROWS][COLS]; + +int main(void) +{ + int row, col; + for (row = 0; row < ROWS; row++) + for(col = 0; col < COLS; col++) + multi[row][col] = row*col; + for (row = 0; row < ROWS; row++) + for(col = 0; col < COLS; col++) + { + printf("\n%d ",multi[row][col]); + printf("%d ",*(*(multi + row) + col)); + } + return 0; +} +----------------- end of program 6.1 --------------------- + + Because of the double de-referencing required in the pointer +version, the name of a 2 dimensional array is said to be a +pointer to a pointer. With a three dimensional array we would be +dealing with an array of arrays of arrays and a pointer to a +pointer to a pointer. Note, however, that here we have initially +set aside the block of memory for the array by defining it using +array notation. Hence, we are dealing with an constant, not a +variable. That is we are talking about a fixed pointer not a +variable pointer. The dereferencing function used above permits +us to access any element in the array of arrays without the need +of changing the value of that pointer (the address of multi[0][0] +as given by the symbol "multi"). + +EPILOG: + + I have written the preceding material to provide an +introduction to pointers for newcomers to C. In C, the more one +understands about pointers the greater flexibility one has in the +writing of code. The above has just scratched the surface of the +subject. In time I hope to expand on this material. Therefore, +if you have questions, comments, criticisms, etc. concerning that +which has been presented, I would greatly appreciate your +contacting me using one of the mail addresses cited in the +Introduction. + +Ted Jensen diff --git a/reference/C/CONTRIB/SNIP/pushdir.c b/reference/C/CONTRIB/SNIP/pushdir.c new file mode 100755 index 0000000..362922c --- /dev/null +++ b/reference/C/CONTRIB/SNIP/pushdir.c @@ -0,0 +1,192 @@ +/* +** PushDir() and PopDir() +** +** Original Copyright 1988-1991 by Bob Stout as part of +** the MicroFirm Function Library (MFL) +** +** This subset version is an expanded version of the one +** originally published by the author in Tech Specialist +** magazine and is hereby donated to the public domain. +*/ + +#include <dos.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> + +#ifdef __TURBOC__ + #include <dir.h> +#else + #include <direct.h> +#endif + +#define DIR_STACK_SIZE 8 +#define MAX_FLEN 67 + +typedef enum {ERROR = -1, FALSE, TRUE} LOGICAL; + +#define BOOL(x) (!(!(x))) + +/* +** NOTE: Uses the author's chdrv(), also in SNIPPETS! +*/ + +int chdrv(int); + +static int PushDir_stack_ptr; +static char PushDir_stack[DIR_STACK_SIZE][MAX_FLEN]; + +/* +** PushDir() +** +** Like chdir(), except a drive may be specified and the old directory +** is saved. +** +** Arguments: 1 - newdir, the buffer containing the new directory name +** +** Returns: -1 - stack overflow +** 0 - error +** 1 - success, still on same drive +** 2 - success, changed drive +** +** Side effects: Converts name in newdir to upper case and prepends +** a drive letter. +** +** CAUTION: Since a drive will be prepended to newdir, it's buffer +** should be at at least MAX_FLEN long. +*/ + +int PushDir(char *newdir) +{ + char pname[MAX_FLEN]; + char drive[3]; + char *target = &pname[2]; + int new_drv = 0, ercode = 0; + static int init = 0; + + if (!init) + PushDir_stack_ptr = init = -1; + if (DIR_STACK_SIZE <= ++PushDir_stack_ptr) + { + ercode = -1; + goto ErrEx; + } + getcwd(PushDir_stack[PushDir_stack_ptr], MAX_FLEN); + strupr(PushDir_stack[PushDir_stack_ptr]); + strncpy(drive, PushDir_stack[PushDir_stack_ptr], 2); + drive[2] = '\0'; + if (':' == newdir[1]) + { /* If a drive is specified */ + strupr(newdir); + strcpy(pname, newdir); + if (strchr(target, ':')) /* if filename is illegal */ + goto ErrEx; + if (*drive != *newdir) + { + if (ERROR == chdrv(newdir[0] - 'A')) + { /* If the drive is invalid */ + goto ErrEx; + } + else new_drv = 1; + } + } + else + { /* If a drive isn't specified */ + if (!strchr(strupr(newdir), ':')) + { /* If legal filename */ + strcpy(pname, drive); + strcat(pname, newdir); + strcpy(newdir, pname); + } + else + { /* If filename is illegal */ + goto ErrEx; + } + } + + if (*target) + { + if (chdir(target)) + { + if (1 == new_drv) /* We already changed drives */ + chdrv(*drive - 'A'); /* Go home before exit */ + goto ErrEx; + } + } + return (new_drv + 1); +ErrEx: + --PushDir_stack_ptr; + return (ercode); +} + +/* +** PopDir() +** +** Like chdir(), except goes to the drive/directory specified on the +** top of the PushDir stack. +** +** Arguments: none +** +** Returns: -1 - stack empty +** 0 - error - stack pointer unchanged +** 1 - success, still on same drive +** 2 - success, changed drive +** +** Side effects: none +** +** CAUTION: chdir() or chdrv() should not be called between PushDir- +** PopDir calls. +*/ + +int PopDir(void) +{ + char I_am_here[MAX_FLEN], target_drv, *target; + int new_drv = 0; + + if (0 > PushDir_stack_ptr) + return -1; + getcwd(I_am_here, MAX_FLEN); + target = &PushDir_stack[PushDir_stack_ptr][2]; + target_drv = PushDir_stack[PushDir_stack_ptr][0]; + if (I_am_here[0] != target_drv) + { + if (ERROR == chdrv(target_drv - 'A')) + return 0; + new_drv = 1; + } + if (!chdir(target)) + { + --PushDir_stack_ptr; + return (1 + new_drv); + } + else return 0; +} + +/* +** isdir() +** +** Checks to see if a drive and/or path are a valid directory. +** +** Arguments: 1 - dir, the buffer containing the new directory name +** +** Returns: ERROR - push/popdir stack overflow +** FALSE - not a valid directory +** TRUE - valid directory +** +** Side effects: Converts name in dir to upper case and prepends a +** drive letter. +** +** CAUTION: Since a drive will be prepended to newdir, it's buffer +** should be at at least MAX_FLEN long. +*/ + +int isdir(char *dir) +{ + int ercode; + + if (-1 == (ercode = PushDir(dir))) + return ercode; + if (ercode) + PopDir(); + return BOOL(ercode); +} diff --git a/reference/C/CONTRIB/SNIP/query.c b/reference/C/CONTRIB/SNIP/query.c new file mode 100755 index 0000000..04f72ce --- /dev/null +++ b/reference/C/CONTRIB/SNIP/query.c @@ -0,0 +1,51 @@ +/* +** QUERY.C - Timed query with default for batch files +** +** public domain by Bob Stout +*/ + +#include <stdio.h> +#include <time.h> +#include <ctype.h> +#include <stdlib.h> +#include <conio.h> + +main(int argc, char *argv[]) +{ + int ch = '\0', def_ch = '\0'; + char *prompt = "(y/n) "; + clock_t start, limit = (clock_t)0; + + if (1 < argc) + { + def_ch = toupper(*argv[1]); + if ('Y' == def_ch) + prompt[1] = (char)def_ch; + else if ('N' == def_ch) + prompt[3] = (char)def_ch; + else def_ch = '\0'; + } + fputs(prompt, stderr); + if (2 < argc) + { + start = clock(); + limit = (clock_t)(CLK_TCK * atoi(argv[2])); + } + while ('Y' != ch && 'N' != ch) + { + while (!kbhit()) + { + if (limit && (limit <= (clock() - start))) + { + ch = def_ch; + goto BYE; + } + } + ch = toupper(getch()); + if ('Y' != ch && 'N' != ch && (1 < argc)) + ch = def_ch; + }; +BYE: fputc(ch, stderr); + fputc('\n', stderr); + return ('Y' == ch); +} diff --git a/reference/C/CONTRIB/SNIP/rand1.c b/reference/C/CONTRIB/SNIP/rand1.c new file mode 100755 index 0000000..b596fa5 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/rand1.c @@ -0,0 +1,239 @@ +/************************************************************************ + This random number generator originally appeared in "Toward a Universal + Random Number Generator" by George Marsaglia and Arif Zaman. + Florida State University Report: FSU-SCRI-87-50 (1987) + + It was later modified by F. James and published in "A Review of Pseudo- + random Number Generators" + + Converted from FORTRAN to C by Phil Linttell, James F. Hickling + Management Consultants Ltd, Aug. 14, 1989. + + THIS IS THE BEST KNOWN RANDOM NUMBER GENERATOR AVAILABLE. + (However, a newly discovered technique can yield + a period of 10^600. But that is still in the development stage.) + + It passes ALL of the tests for random number generators and has a period + of 2^144, is completely portable (gives bit identical results on all + machines with at least 24-bit mantissas in the floating point + representation). + + The algorithm is a combination of a Fibonacci sequence (with lags of 97 + and 33, and operation "subtraction plus one, modulo one") and an + "arithmetic sequence" (using subtraction). + + On a Vax 11/780, this random number generator can produce a number in + 13 microseconds. +************************************************************************/ + +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include <time.h> + +#define TRUE 1 +#define FALSE 0 + +float u[97], c, cd, cm; +int i97, j97, test; + +int rmarin(int ij, int kl); +int ranmar(float rvec[], int len); + + +int main() +{ + + float temp[100]; + int i; + int ij, kl, len; + + /*These are the seeds needed to produce the test case results*/ + + ij = 1802; + kl = 9373; + + /*Do the initialization*/ + + if (1 == rmarin(ij,kl)) + return 1; + + /*Generate 20000 random numbers*/ + + len = 100; + for ( i=0; i<=199 ; i++) + if (1 == ranmar(temp, len)) + return 1; + + /*If the random number generator is working properly, + the next six random numbers should be: + + 6533892.0 14220222.0 7275067.0 + 6172232.0 8354498.0 10633180.0 + */ + + len = 6; + if (1 == ranmar(temp, len)) + return 1; + + for ( i=0; i<=5; i++) + printf("%12.1f\n",4096.0*4096.0*temp[i]); + + return 0; +} + + +/************************************************************************ + This is the initialization routine for the random number generator RANMAR() + NOTE: The seed variables can have values between: 0 <= IJ <= 31328 + 0 <= KL <= 30081 + The random number sequences created by these two seeds are of sufficient + length to complete an entire calculation with. For example, if several + different groups are working on different parts of the same calculation, + each group could be assigned its own IJ seed. This would leave each group + with 30000 choices for the second seed. That is to say, this random + number generator can create 900 million different subsequences -- with + each subsequence having a length of approximately 10^30. + + Use IJ = 1802 & KL = 9373 to test the random number generator. The + subroutine RANMAR should be used to generate 20000 random numbers. + Then display the next six random numbers generated multiplied by 4096*4096 + If the random number generator is working properly, the random numbers + should be: + 6533892.0 14220222.0 7275067.0 + 6172232.0 8354498.0 10633180.0 +************************************************************************/ + +int rmarin(int ij, int kl) +{ + + float s, t; + int i, j, k, l, m; + int ii, jj; + + /* Change FALSE to TRUE in the next statement to test the + random routine.*/ + + test = TRUE; + + if ( ( ij < 0 || ij > 31328 ) || + ( kl < 0 || kl > 30081 ) ) + { + printf ("RMARIN: The first random number seed must have a " + "value between 0 and 31328\n"); + printf (" The second random number seed must have a " + "value between 0 and 30081"); + return 1; + } + + i = (int)fmod(ij/177.0, 177.0) + 2; + j = (int)fmod(ij , 177.0) + 2; + k = (int)fmod(kl/169.0, 178.0) + 1; + l = (int)fmod(kl , 169.0); + + for ( ii=0; ii<=96; ii++ ) + { + s = (float)0.0; + t = (float)0.5; + for ( jj=0; jj<=23; jj++ ) + { + m = (int)fmod( fmod(i*j,179.0)*k , 179.0 ); + i = j; + j = k; + k = m; + l = (int)fmod( 53.0*l+1.0 , 169.0 ); + if ( fmod(l*m,64.0) >= 32) + s = s + t; + t = (float)(0.5 * t); + } + u[ii] = s; + } + + c = (float)( 362436.0 / 16777216.0); + cd = (float)( 7654321.0 / 16777216.0); + cm = (float)(16777213.0 / 16777216.0); + + i97 = 96; + j97 = 32; + + test = TRUE; + + return 0; +} + +int ranmar(float rvec[], int len) +{ + float uni; + int ivec; + + if ( !test ) + { + printf ("RANMAR: Call the initialization routine (RMARIN) " + "before calling RANMAR.\n"); + return 1; + } + + for ( ivec=0; ivec < len; ivec++) + { + uni = u[i97] - u[j97]; + if ( uni < 0.0F ) + uni = uni + 1.0; + u[i97] = uni; + i97--; + if ( i97 < 0 ) + i97 = 96; + j97--; + if ( j97 < 0 ) + j97 = 96; + c = c - cd; + if ( c < 0.0F ) + c = c + cm; + uni = uni - c; + if ( uni < 0.0F ) + uni = uni + 1.0; + rvec[ivec] = uni; + } + return 0; +} + +/* I use the following procedure in TC to generate seeds: + + The sow() procedure calculates two seeds for use with the random number + generator from the system clock. I decided how to do this myself, and + I am sure that there must be better ways to select seeds; hopefully, + however, this is good enough. The first seed is calculated from the values + for second, minute, hour, and year-day; weighted with the second most + significant and year-day least significant. The second seed weights the + values in reverse. +*/ + +void sow( seed1, seed2 ) +int *seed1, *seed2; +{ + struct tm *tm_now; + float s_sig, s_insig, maxs_sig, maxs_insig; + long secs_now; + int s, m, h, d, s1, s2; + + time(&secs_now); + tm_now = localtime(&secs_now); + + s = tm_now->tm_sec + 1; + m = tm_now->tm_min + 1; + h = tm_now->tm_hour + 1; + d = tm_now->tm_yday + 1; + + maxs_sig = (float)(60.0 + 60.0/60.0 + 24.0/60.0/60.0 + + 366.0/24.0/60.0/60.0); + maxs_insig = (float)(60.0 + 60.0*60.0 + 24.0*60.0*60.0 + + 366.0*24.0*60.0*60.0); + + s_sig = (float)(s + m/60.0 + h/60.0/60.0 + d/24.0/60.0/60.0); + s_insig = (float)(s + m*60.0 + h*60.0*60.0 + d*24.0*60.0*60.0); + + s1 = (int)(s_sig / maxs_sig * 31328.0); + s2 = (int)(s_insig / maxs_insig * 30081.0); + + *seed1 = s1; + *seed2 = s2; +} diff --git a/reference/C/CONTRIB/SNIP/rand2.c b/reference/C/CONTRIB/SNIP/rand2.c new file mode 100755 index 0000000..9759671 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/rand2.c @@ -0,0 +1,51 @@ +/******************************************************************** + The McGill Super-Duper Random Number Generator + G. Marsaglia, K. Ananthanarayana, N. Paul + + Incorporating the Ziggurat method of sampling from decreasing + or symmetric unimodal density functions. + G. Marsaglia, W.W. Tsang + + Rewritten into C by E. Schneider + *********************************************************************/ + +static unsigned long mcgn, srgn; + +#define MULT 69069L + +void rstart (long i1, long i2) +{ + mcgn = (unsigned long)((i1 == 0L) ? 0L : i1 | 1L); + srgn = (unsigned long)((i2 == 0L) ? 0L : (i2 & 0x7FFL) | 1L); +} + +long uni(void) +{ + unsigned long r0, r1; + + r0 = (srgn >> 15); + r1 = srgn ^ r0; + r0 = (r1 << 17); + srgn = r0 ^ r1; + mcgn = MULT * mcgn; + r1 = mcgn ^ srgn; + return (r1 >> 1); +} + +long vni(void) +{ + unsigned long r0, r1; + + r0 = (srgn >> 15); + r1 = srgn ^ r0; + r0 = (r1 << 17); + srgn = r0 ^ r1; + mcgn = MULT * mcgn; + r1 = mcgn ^ srgn; + return r1; +} + +/* +"Anyone who consider arithmetic means of producing random number is, + of course, in a state of sin" - John Von Neumann +*/ diff --git a/reference/C/CONTRIB/SNIP/rdxcnvrt.c b/reference/C/CONTRIB/SNIP/rdxcnvrt.c new file mode 100755 index 0000000..3436483 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/rdxcnvrt.c @@ -0,0 +1,49 @@ +/* +** RDXCNVRT.C - Convert between number bases +** +** public domain demo by Bob Stout +*/ + +#include <stdlib.h> +#ifdef TEST + #include <stdio.h> +#endif + +/* +** Calling parameters: 1 - Number string to be converted +** 2 - Buffer for the converted output +** 3 - Radix (base) of the input +** 4 - Radix of the output +** +** Returns: Pointer to converted output +*/ + +char *radix_convert(const char *in, char *out, int rin, int rout) +{ + long n; + char *dummy; + + n = strtol(in, &dummy, rin); + return ltoa(n, out, rout); +} + +#ifdef TEST + +int main(int argc, char *argv[]) +{ + int rin, rout; + char buf[40]; + + if (4 > argc) + { + puts("Usage: RDXCNVRT <number> <base_in> <base_out>"); + return(-1); + } + rin = atoi(argv[2]); + rout = atoi(argv[3]); + printf("%s (base %d) = %s (base %d)\n", argv[1], rin, + radix_convert((const char *)argv[1], buf, rin, rout), rout); + return 0; +} + +#endif diff --git a/reference/C/CONTRIB/SNIP/read.me b/reference/C/CONTRIB/SNIP/read.me new file mode 100755 index 0000000..19caa04 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/read.me @@ -0,0 +1 @@ +Before you start, read SNIPPETS.TXT for instructions and information. diff --git a/reference/C/CONTRIB/SNIP/reboot.c b/reference/C/CONTRIB/SNIP/reboot.c new file mode 100755 index 0000000..88a93d0 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/reboot.c @@ -0,0 +1,32 @@ +/* +** Public domain demo to reboot a PC +*/ + +#ifdef __TURBOC__ + #define FAR far +#else + #define FAR _far +#endif + +short FAR *bios_post = (short FAR *)0x00400072; +void (FAR * boot)(void) = (void (FAR *)())0xffff0000; + +void reboot(warm) +{ + if (warm) + *bios_post = 0x1234; + else *bios_post = 0; + boot(); +} + +#ifdef TEST + +#include <stdio.h> + +void main(void) +{ + puts("The computer should do a cold start"); + reboot(0); +} + +#endif /* TEST */ diff --git a/reference/C/CONTRIB/SNIP/redir.c b/reference/C/CONTRIB/SNIP/redir.c new file mode 100755 index 0000000..5d04404 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/redir.c @@ -0,0 +1,59 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + +Program: REDIR.C +Author: F. PIETTE (2:293/2201.135) +Object: Demonstration of the output redirection +Creation: Augustus 2, 1991 +Updates: + + + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +#include <stdio.h> +#include <stdlib.h> +#include <io.h> +#include <fcntl.h> +#include <sys/types.h> +#include <sys/stat.h> + +void main(void) +{ + int old_fh; + int new_fh; + + fprintf(stdout, "This goes to the original standard output\n"); + + /* Duplicate the stdout file handle to restore it later */ + old_fh = dup(fileno(stdout)); + if (old_fh == -1) { + fprintf(stderr, "dup error\n"); + exit(1); + } + + /* Open the new file for output */ + if ((new_fh = open("redir.txt", O_CREAT | O_TRUNC | O_WRONLY, + S_IREAD | S_IWRITE)) == -1) { + fprintf(stderr, "Unable to open redir.txt\n"); + exit(1); + } + /* Duplicate the new handle to stdout */ + dup2(new_fh, fileno(stdout)); + /* We don't need new_fh any more, so close it */ + close(new_fh); + + /* stdout is now redirected, let's try it */ + fprintf(stdout, "This goes to redir.txt file !\n"); + + /* If you run a program using spawn(), the child program will have */ + /* its output redirected to REDIR.TXT file ! */ + + /* Now let's restore stdout to its original state */ + fflush(stdout); /* First flush the outut buffer */ + /* Then duplicate the original file handle to stdout */ + dup2(old_fh, fileno(stdout)); + + /* Let's try if we canceled the redirection */ + fprintf(stdout, "Back to original stdout\n"); + + exit(0); +} diff --git a/reference/C/CONTRIB/SNIP/remtab.c b/reference/C/CONTRIB/SNIP/remtab.c new file mode 100755 index 0000000..d2822c7 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/remtab.c @@ -0,0 +1,63 @@ +/* remtab.c 12-4-91 Robert Mashlan, Public Domain + modified 28 mar 93 by Bob Stout + + Filter for removing tabs. All tabs in the input will be replaced + with spaces. This filter takes one optional command line + parameter, which specifies the number spaces to replace for a tab. + If no size is specifies, it defaults to 8. + + example usage: + + remtab 6 < tabbed.c > untabbed.c + +*/ + +#include <stdio.h> +#include <stdlib.h> + +#define BUFSIZE 4096 + + +int main(int argc, char **argv ) +{ + int tabsize = 8; + + if (argc > 1) /* look for command line parameter */ + { + if (0 == (tabsize = atoi(argv[1]))) + tabsize = 8; + } + + while (1) + { + char buf[BUFSIZE]; + int nr, i, j, pos = 0; + + nr = fread(buf, 1, sizeof(buf), stdin); + for (i = 0; i < nr; i++) + { + switch (buf[i]) + { + case '\t': /* replace tabs with spaces */ + for(j = pos % tabsize; j < tabsize; ++j) + { + putchar(' '); + ++pos; + } + break; + + case '\n': /* start a new line */ + pos = -1; /* this will become 0 when... */ + + /* ...we fall through to... */ + + default: + putchar(buf[i]);/* send character through unchanged */ + ++pos; + } + } + if (nr < sizeof(buf)) + break; + } + return 0; +} diff --git a/reference/C/CONTRIB/SNIP/resource.lst b/reference/C/CONTRIB/SNIP/resource.lst new file mode 100755 index 0000000..e674f64 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/resource.lst @@ -0,0 +1,459 @@ +The following are a list of resources that I've put together from +recommendations in the FidoNet C_Echo. These include books, +magazines and compiler vendors. + +The format for book entries is as follows: + +Author _Title_, ISBN, Publisher, Year, List Price (Comments -- + Recommmended-By) + +Prices are in $US unless otherwise specified. Where a book has been +recommended by multiple persons, I've left off the names that don't +have comments. Books are in alpha order by author's last name, or +title if the author is unknown or unattributed. When there is more +than one ISBN or price, the following suffixes will be used: + +.p -- paperback +.h -- hardback +.d -- with disk + +Magazine information includes the name of the magazine and the address +and subscription rates. + +I cannot list information I do not have. It is possible that some +information may be missing for a particular book. Comments are +condensed from the messages I got the recommendation from and may or may +not accurately describe the book. Lest they take over C_ECHO, any and +all additions/corrections/suggestions should be sent to me netmail at +1:106/2000.25. + +[DISCLAIMER: I make no promises real or implied as to the usefulness of +any of the books here listed. The reason for the 'recommended by' is +to give you some idea of who thought the book was good so you can find +books that are recommended by folks whose messages make particular sense +to you. (Or folks who forgot to mention author/ISBN/publisher/price so +you can harass them.) These people are not in any position to promise +you anything, either.] + +In response to a request by the FidoNet C_Echo moderator, I'm +soliciting longer blurbs about any and all resources listed here. +Please answer the following questions, either individually, or cover +the answers to most of them in a paragraph or so about the book. + +a) Title or other information sufficient for me to determine what + the heck you're writing about +b) When you last read/looked at the book (if it's been a long time, + I'll need to take that into account when selecting whose comments + to use) +c) A brief description. +d) A list of subjects where the book should be listed +e) It's target audience (pick one or more of the following: + beginner, intermediate, skilled, advanced, expert) +f) Your opinion of the useability/readability/understandibilty of + the book +g) What types of folks you'd recommend it to +h) What types of folks you'd recommend to pass it by + +...and anything you think I forgot. + +Your cooperation will be appreciated and your name will be listed as +a contributor. + +- J-Mag Guthrie +1:106/2000.25 +1:106/1393 + +----[ Beginning of book list - last updated 8 Oct 1993 ]---------------------- + +Abramowitz, Milton and Stegun, Irene _Handbook of Mathematical + Functions_, 0-486-61272-4, Dover Publications, 1972, $21.95 (Bob + Jarvis) + +Abrash, Michael _Power Graphics Programming_, 0-88022-500-9, QUE, 1989 + (out of print) + +_Advanced C Programming_, Brady Publishing Group + +Aho, Sethi, and Ullman _Compilers: Principles, Techniques, and Tools_ + +Atkinson and Atkinson _Using Borland C++_, QUE (Steven Owen) + +Banahan, Mike _The C Book_ (Tom Donahue) + +Bentley, Jon, _More Programming Pearls - Confessions of a Coder_, + 0-201-11889-0, Addison-Wesley, 1990, $18.25 + +Bentley, Jon _Programming Pearls_, 0-201-10331-1, Addison-Wesley, 1986, + $18.25 + +Bentley, Jon _Writing Efficient Programs_ + +Booch, Grady _Object Oriented Design with Applications_, 0-8053-0091-0, + Benjamin/Cummings Publishing, 1991 + +Brooks, Fred _The Mythical Man-Month: Essays on Software Engineering_, + 0-201-00650-2, Addison-Wesley, 1975 + +Brown, Ralf and Kyle, Jim, _PC Interrupts_, 0-201-57797-6, Addison- + Wesley, 1991, $32.95 + +Campbell, Joe _C Programmer's Guide to Serial Communications_, + 0-672-22584-0, Howard W. Sams & Co, 1987, $26.95 (Does not talk about + RTS/CTS handshaking [which is] vital for creating a modern terminal + program. -- Jon Guthrie) + +Davis, Stephen R. _Hands-On Turbo C++_, 0-201-57052-1, Addison-Wesley + (Daniel Lo) + +_DOD Programmer's Reference, 3rd Edition_ Que (Robert Johnstone) + +Duncan, Ray; Petzold, Charles; Shulman, Andrew; Baker, M. Steven; + Nelson, Ross P.; Davis, Stephen R.; Moote, Robert _Extending DOS_, + 0-201-56798-9, Addison-Wesley, 1992, $26.95 + +Ellis, Margaret and Stroustrup, Bjarne _The Annotated C++ Reference + Manual_, 0-201-51459-1, Addison-Wesley, 1990, (Bob Jarvis) + +Gorlen, Keith E.; Orlow, Sanford M.; and Plexico, Perry S. _Data Abstraction + and Object-Oriented Programming in C++_, 0-471-92346-X, John Wiley & + Sons, 1990 (Bob Stout) + +Ferraro, Richard _The Programmer's Guide to the EGA and VGA Cards, 2nd + Edition_ 0-201-57025-4, Addison Wesley, $34.95, CAN$44.95 + +Foerster, Scott _The Printer Bible_, 0-88022-512-2, QUE Books, 1990, + $24.95, CAN$31.95, UK#22.95 + +Goodwin, Mark _Serial Communications in C and C++_, MIS Press, $29.95, + $49.95d + +Hekmatpour, Sharam _C++ - A Guide for C Programmers_, 0-13-109471-8, + Prentice Hall, 1990 + +Harbison, Samuel P. and Steele, Guy L. Jr. _C, a Reference Manual (third + edition)_, 0-13-110933-2, Prentice Hall, 1991 + +Hogan, Thom _The Programmer's PC Sourcebook (Second Edition)_, + 1-55615-321-X, Microsoft Press, 1991, $39.95 + +Holub, Allen _Compiler Design in C_, 0-13-155045-4, Prentice Hall, 1990 + +Horton, Mark R. _Portable C Software_, 0-13-868050-7, Prentice Hall, + 1990 (Bob Stout) + +James, Geoffrey _The Tao of Programming_, 0-981137-07-01-795 + +Jourdain, Robert and The Peter Norton Computing Group _The Programmer's + Problem Solver_ + +Kay, David C., and Levine, John R. _Graphics File Formats_ + 0-8306-3059-7.p, 0-8306-3060-0.h, Tab/Windcrest/McGraw-Hill, 1992 + (primarily a file format reference and does not give programming + examples -- David Harmon) + +Kernighan, Brian W. and Ritchie, Dennis M. _The C Programming Language_ + 0-13-11-163-3, 0-13-110362-8, Prentice Hall (two editions, informally + K&R and K&R2) + +Knuth, Donald _Sorting and Searching_, Addison Wesley (Knuth is a Vulcan + -- Terry Carmen) + +Kosko, Bert _Neural Networks and Fuzzy Systems: A Dynamical Systems + Approach to Machine Intelligence_, 1992, $56.95 (2 Disks -- Eric Ford) + +Koenig, Andrew _C Traps and Pitfalls_, 0-201-17928-8 + +LaFore, Robert _Turbo C, Programming for the PC_ Waite Group (Ray + Parker) + +Lapin, J.E. (pseudonym) _Portable C and Unix System Programming_, + 0-13-686494-5, Prentice-Hall, 1987 (Bob Stout) + +Leblanc, Gerard _MaŒtrise de Turbo C_, Eyrolles Editions (in French -- + Francis Peree) + +Lewine, Donald _POSIX Programmer's Guide_, 0-937175-73-0, O'Reilly & + Associates, Inc., 1991, $34.95 + +Lindley, Craig A. _Practical Image Processing in C_, 0-471-54377-2 (Joe + Angert) + +Mayer, Bertrand _Object-oriented Software Construction_, 0-13-629049-3, + Prentice Hall (Mike Taylor) + +McCord, James W. _C Programmer's Guide to Graphics_, 0-672-22784-3, SAMS, + $29.95, $37.95 CAN (Branko Dragicevic) + +McGregor, John and Sykes, David _Object-Oriented Software Development: + Engineering Software for Reuse_, 0-442-00157-6, Van Nostrand Reinhold, + 1992 (Bob Jarvis) + +_Microsoft MS-DOS Programmer's Reference_, 1-55615-329-5, Microsoft + Press, 1991, $24.95 (Bob Jarvis) + +Nance, Barry _Network Programming in C_, Que Books (Steve Cox) + +Nelson, Mark _The Data Compression Handbook_, 1-55851-214-4, + 1-55851-216-0 M&T Books, $29.95, $36.95.d (Oliver Reubens) + +Norton, Peter and Wilton, Richard _The NEW Peter Norton Programmer's + Guide to the IBM PC & PS/2_, 1-55615-131-4, Microsoft Press + +Oualline, Steve _Practical C Programming_, 0-937175-65-X, O'Reilly & + Associates (David Gersic) + +Perry, Greg and Johnson, Marcus _Turbo C++ By Example_ 0-88022-812-1, + Que + +Petzold, Charles _Programming Windows 3.1_, 1-55615-395-3, MicroSoft + Press + +Plauger, P. J. _The Standard C Library_, 0-13-131509-9, Prentice Hall, + 1992 + +Plauger, P. J. _Standard C: Programmer's Quick Reference_, + 1-55615-158-6, Microsoft Press, 1989, $7.95 + +Press, William H.; Flannery, Brian P.; Teukolsky, Saul A.; and + Vetterling, William T., _Numerical Recipes: The Art of Scientific + Computing_, 0-521-30811-9, Cambridge University Press, 1986 + +Press, William et. al. _Numerical Recipes in C_ (the C version of the + above -- J-Mag) + +Qualline, Steve _C Elements of Style_ 1-55851-291-8, M&% Books + +Radcliffe, Robert _Encyclopedia C_ 0-89588-655-3 (Microsoft C specific) + +Remer, Daniel and Dunaway, Robert _Legal Care for Your Software (4th + Edition)_, 87337-037-6, RDS Publishing Company, $39.95 + +Rimmer, Steve _Bit-Mapped Graphics_, 0-8306-3558-0, Windcrest/McGraw- + Hill + +Rimmer, Steve _Supercharged Bit-Mapped Graphics_, 0-8306-3788-5, + Windcrest/McGraw-Hill + +Rose, Charles G. _Programmer's Guide to NetWare_, 0-07-607029-8, + Mcgraw-Hill + +Salone, M. J. _How to Copyright Software_, NOLO Press. (George Milliken) + +Schildt, Herbert _Advanced C_, 0-07-881348-4, Osborne McGraw-Hill, + $21.95 + +Schildt, Herbert _ANSI C Made Easy_, 0-07-881500-2, Osborne McGraw-Hill, + $19.95 + +Schildt, Herbert _ANSI C Made Easy (Spanish)_, 84-76156030, Osborne + McGraw-Hill + +Schildt, Herbert _Artificial Intelligence Using C_, 0-07-881255-0, + Osborne McGraw-Hill, $24.94 + +Schildt, Herbert _The Art of C_, 0-07-881-691-2.d, Osborne-McGraw-Hill, + 1991, $39.95.d + +Schildt, Herbert _Born to Code in C_, 0-07-881468-5, Osborne + McGraw-Hill, $28.95 + +Schildt, Herbert _C: The Pocket Reference_, 0-07-881321-2, Osborne + McGraw-Hill, $5.95 + +Schildt, Herbert _C: The Pocket Reference (Spanish)_, 84-76152175, + Osborne McGraw-Hill + +Schildt, Herbert _C: Power User's Guide_, 0-07-881307-7, Osborne + McGraw-Hill, $22.95 + +Schildt, Herbert _C: Power User's Guide (Spanish)_, 84-76153813, Osborne + McGraw-Hill + +Schildt, Herbert _C: The Complete Reference_, 0-07-881538-X, Osborne + McGraw-Hill, $28.95 + +Schildt, Herbert _C++: The Complete Reference_, 0-07-881654-8, Osborne + McGraw-Hill, $29.95 + +Schildt, Herbert _Teach Yourself C_, 0-07-881596-7, Osborn McGraw-Hill, + $19.95 + +Schildt, Herbert _Turbo C++: The Complete Reference_, 0-07-881535-5, + Osborne McGraw-Hill, $29.95 + +Schildt, Herbert _Using Turbo C++_, 0-07-881610-6, Osborne McGraw-Hill, + $24.95 + +Schulman, Andrew, et al. _Undocumented DOS_, 0-201-570649-5, Addison Wesley, + 1990, $39.95 (one portion of..."et al."...Ralf Brown -- Brian + Dunworth) + +Schwaderer, David _C Programmer's Guide to NETBIOS_ (Dimitri Van de + Ville) + +Sedgewick, Robert _Algorithms in C_, 0-201-51425-7, Addison-Wesley, + 1990 + +Selby, Samual M. _Standard Mathematical Tables_, The Chemical Rubber + Company, 1970 + +Shlaer, Sally and Mellor, Stephen _Object Lifecycles : Modeling the + World in States_, 0-13-629940-7, Yourdon Press, 1992 (Bob Jarvis) + +Shlaer, Sally and Mellor, Stephen _Object-Oriented Systems Analysis : + Modeling the World in Data_, 0-13-629023-X, Yourdon Press, 1988 (Bob + Jarvis) + +Stevens, Al _C Database Development, 2nd Ed._, 1-5528-135-5, MIS Press, + $24.95, $49.95.d + +Stevens, Al _Extending Turbo C Professional_ + +Stevens, Al _Turbo C Memory Resident Utilities, Screen I/O and + Programming Techniques_, 0-943518-35-0, MIS Press + +Stoltz, Axel _The Soundblaster Book_ 1-55755-164-2, Abacus, 34.95, + CAN$44.95 + +Straker, David _C Style: Standards & Guidelines_ 0-13-116898-3, + Prentice-Hall + +Stroustrup, Bjarne _The C++ Programming Language - 2nd Edition_ + (more current than the ARM, but less official -- Bob Stout) + +_Supercharged Bitmapped Graphics_ TAB books (Jim Mooney) + +Swan, Tom _Learning C++_, 0-672-22785-1, SAMS, 1991 (Comes with working + demo version of Zortech C++ -- Bram Smits) + +Swan, Tom _Mastering Borland C++_, 0-672-30274-8, SAMS, 1992, + $39.95d (ANSI C, C++, extensive examples and answers for the + exercises -- Scott Remick) + +Tisher, Michael _PC Intern_, 1-55755-145-6 ( Patrick Tousignant) + +Tondo, Clovis L., Nathanson, Andrew, Yount, Eden _Mastering Make_, + 0-13-554619-2, Prentice Hall, 1992, $25.75 + +Traister, Robert J _Mastering C Pointers_, 0-12-697408-X, Academic + Press, 1990 (Tom Donahue) + +Van Wyk, Christopher J. _Data Structures and C Programs_,0-201-16116-8, + Addison-Wesley (David Gersic) + +Voss, Greg and Chui, Paul (unknown title), 0-07-881526-6, + Borland/Osborne/McGraw Hill (a C++ tutorial -- Phil Sharp) + +_The Waite Group's Essential Guide to ANSI C_, 0-672-22673-1, Howard W. + Sams, 1989, $7.95, (out of print but worth searching for - the best + pocket-sized C handbook available -- Bob Stout) + +_The Waite Group's New C Primer Plus_, 0-672-22687-1 (Dale Furneaux) + +Waite and Prata, _C: Step by Step_, 0-672-22651-0 + +Wiener, Richard and Pinson, Lewis _An Introduction to Object-Oriented + Programming and C++_, 0-201-15413-7, Addison-Wesley, 1988 $31.68 (Bob + Jarvis) + +Wilton, Richard _Programmer's Guide to PC & PS/2 Video Systems_, + 1-55615-103-9, Microsoft Press, 1987, $24.95 (Bob Jarvis) + +Young, Michael J. _System Programming in Microsoft C_, Sybex (Nhan Tran) + +----[ End of book list ]------------------------------------------------------ + +----[ Begin magazine list ]--------------------------------------------------- + +DDJ (Dr. Dobbs Journal) +P.O. Box 56188 +Boulder, CO 80322-6188 +U.S.A. +Canada & Mexico: $45/yr (surface) +Other countries: $70/yr (air) +Domestic (US): #29.97/yr + +The C Users Journal +1601 W. 23rd St., Suite 200 +Lawrence, KS 66046-9950 +US discount rate: $29.95/yr +Canada/Mexico: $54/yr +Other countries: $65/yr (air) + +C++ Report +Subscriber Services, Dept CPR +P.O. Box 3000 +Denvill NJ 07834-9979 +Domestic US: $69/yr +Foreign & Canada: $94/yr (air) + +AI Expert +P.O. Box 51241 +Boulder, CO 80321-1241 +US discount rate: $32/yr (basic rate: $42) +Canada/Mexico: $32+$6/yr +Other countries: $32 +15/yr (surface) or +40/yr (air) + +----[ End magazine list ]----------------------------------------------------- + +----[ Begin support phone list ]---------------------------------------------- + +Borland (Turbo C/C++, Borland C/C++) + Customer Service: + Customer Service (all products) 408-461-9000 + (7am-4pm PT Monday-Friday) + Order Desk (Credit Card orders only) 800-331-0877 + (7am-4pm PT Monday-Friday) + Technical Support: + Technical support for the following products is available from + 6am-5pm PT, Monday-Friday: + C++ 408-461-9133 + Paradox Engine for C/C++ 408-461-9133 + Resource Workshop for C/C++ 408-461-9133 + Turbo Vision for C/C++ 408-461-9133 + 900-Advisor Line + When you need a fast response or a more advanced level of + technical support, you can call the 900-Advisor Line. Technical + support for the following products is available from 6am-5pm PT, + Monday-Friday. You gain access within one minute. Each call is + $2.00 per minute (the first minute is free). + Borland C++ (Windows) 900-555-1002 + Borland C++ (DOS) 900-555-1004 + Other Services: + The following services are available 7 days a week, 24 hours a + day. + Online Automated Support (modem) + (8 data bits, no parity, 1 stop bit) 408-431-5250 + TechFax (Automated FAX retrieval) 800-822-4269 + Download Bulletin Board System (modem) + (8 data bits, no parity, 1 stop bit) 408-439-9096 + For more information about the services listed below, you may + order the appropriate document from our TechFax system by dialing + 800-822-4269. + TechFax + Service Document + Online Automated Support 9606 + TechFax 9652 + Download Bulletin Board System 9604 + +Dunfield Develpment Systems (Micro C) + Dunfield Development Systems + P.O. Box 31044 + Nepean, Ontario (Canada) + K2B 8S8 + + VOICE: (613) 256-5820 [Between 0800-1900 EST please!] + FAX: (613) 256-5821 [0800-1900 EST Mon-Fri] + BBS: (613) 256-5820 [1900-0800 EST Mon-Fri, All day Sat-Sun] + (300/1200/2400 Dial '2' when autoattendant answers). + +Mix Software + Mix Software + 1132 Commerce Dr. + Richardson, Tx 75081 + + Order: 1-800-333-0330 + Tech: 1-214-783-6001 + Fax: 1-214-783-1404 + +----[ End support phone list ]------------------------------------------------ diff --git a/reference/C/CONTRIB/SNIP/rfind1st.c b/reference/C/CONTRIB/SNIP/rfind1st.c new file mode 100755 index 0000000..8320ec6 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/rfind1st.c @@ -0,0 +1,156 @@ +/* +** RFIND1ST.C - Our own non-compiler specific find first/next calls +** +** Original Copyright 1988-1991 by Bob Stout as part of +** the MicroFirm Function Library (MFL) +** +** This subset version is functionally identical to the +** version originally published by the author in Tech Specialist +** magazine and is hereby donated to the public domain. +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <dos.h> +#include "dirent.h" +#ifndef OS2 + +/************************************************************************/ +/* */ +/* rfind_1st() - Find first matching file */ +/* */ +/* Parameters: 1 - Drive, path and filename of file to be found. May */ +/* include wildcards */ +/* 2 - Attribute of file to search for. Attributes are */ +/* described in the MS-DOS manual. The search strategy */ +/* is described under DOS call 0x4Eh. */ +/* 3 - Disk transfer area buffer. If NULL, one will be */ +/* malloc'ed. */ +/* Returns: Pointer to a struct DSTRUCT. If error, NULL is returned and */ +/* _doserrno is set to the error #. */ +/* */ +/************************************************************************/ + +struct DSTRUCT *rfind_1st(char *name, unsigned attribute, struct DSTRUCT *dta) +{ + struct DSTRUCT *my_dta; + union REGS regs; + + if (NULL == dta) + my_dta = (struct DSTRUCT *)malloc(sizeof(struct DSTRUCT)); + else my_dta = dta; + + bdos(0x1A, (unsigned)my_dta, 0); /* set DTA to my_dta */ + regs.x.ax = 0x4E00; /* find first */ + regs.x.dx = (unsigned)name; + regs.x.cx = attribute; + intdos(®s, ®s); + if (regs.x.cflag) /* if error */ + { + _doserrno = regs.x.ax; + if (NULL == dta && my_dta != NULL) + free(my_dta); + return (struct DSTRUCT *) NULL; + } + return my_dta; +} + +/************************************************************************/ +/* */ +/* rfind_nxt() - Find next matching file */ +/* */ +/* Parameters: 1 - Pointer to DSTRUCT structure to use */ +/* */ +/* Returns: Pointer to struct DSTRUCT, */ +/* NULL if no more matching files found */ +/* */ +/************************************************************************/ + +struct DSTRUCT *rfind_nxt(struct DSTRUCT *dta) +{ + union REGS regs; + + bdos(0x1A, (unsigned)dta, 0); /* set DTA to dta */ + regs.x.ax = 0x4F00; + intdos(®s,®s); + if (regs.x.cflag) /* if error */ + { + _doserrno = regs.x.ax; + return (struct DSTRUCT *) NULL; + } + return dta; +} + +#else + +/************************************************************************/ +/* */ +/* OS/2 Versions follow - poorly tested! */ +/* */ +/************************************************************************/ + +#if OS2 < 2 + typedef USHORT UWORD +#else + typedef ULONG UWORD +#endif + +static HDIR hdir_ptr = DSIR_CREATE; +#if OS2 < 2 + static FILEFINDBUF flist; +#else + static FILEFINDBUF3 flist; +#endif + +static PSZ fname; +static UWORD count = 1; + +struct DSTRUCT *rfind_1st(char *name, unsigned attribute, struct DSTRUCT *dta) +{ + struct DSTRUCT *my_dta; + short retval; + + if (NULL == dta) + my_dta = (struct DSTRUCT *)malloc(sizeof(struct DSTRUCT)); + else my_dta = dta; + + fname = (PSZ)name; +#if OS2 < 2 + if (DosFindFirst(fname, &hdir_ptr, attribute, &flist, sizeof(flist), + &count, 0L)) +#else + if (DosFindFirst(fname, &hdir_ptr, attribute, &flist, sizeof(flist), + &count, FIL_STANDARD)) +#endif + { + return NULL; + } + else + { + my_dta->ATTRIBUTE = (BYTE)(flist.attrFile & 0xff); + my_dta->TIME = flist.ftimeCreation; + my_dta->DATE = flist.fdateCreation; + my_dta->FSIZE = flist.cbFile; + strcpy(my_dta->NAME, flist.achName); + return my_dta; + } +} + +struct DSTRUCT *rfind_nxt(struct DSTRUCT *dta) +{ + struct DSTRUCT *my_dta; + + if (DosFindNext(hdir_ptr, &flist, sizeof(flist), & count)) + return NULL; + else + { + my_dta->ATTRIBUTE = (BYTE)(flist.attrFile & 0xff); + my_dta->TIME = flist.ftimeCreation; + my_dta->DATE = flist.fdateCreation; + my_dta->FSIZE = flist.cbFile; + strcpy(my_dta->NAME, flist.achName); + return my_dta; + } +} + +#endif diff --git a/reference/C/CONTRIB/SNIP/rg_isort.c b/reference/C/CONTRIB/SNIP/rg_isort.c new file mode 100755 index 0000000..dc08533 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/rg_isort.c @@ -0,0 +1,18 @@ +/* +** insort() -- insertion sort an array of string pointers via strcmp() +** public domain by Ray Gardner Denver, CO 12/91 +*/ + +void strsort(char **v, int n) +{ + int i, j; + char *vtmp; + + for (i = 1; i < n; ++i) + { + vtmp = v[i]; + for ( j = i - 1; j >= 0 && strcmp(v[j], vtmp) > 0; --j ) + v[j+1] = v[j]; + v[j+1] = vtmp; + } +} diff --git a/reference/C/CONTRIB/SNIP/rg_qsort.c1 b/reference/C/CONTRIB/SNIP/rg_qsort.c1 new file mode 100755 index 0000000..d770517 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/rg_qsort.c1 @@ -0,0 +1,150 @@ +/******************************************************************/ +/* qsort.c -- Non-Recursive ANSI Quicksort function */ +/* */ +/* Public domain by Raymond Gardner, Englewood CO February 1991 */ +/* */ +/* Usage: */ +/* qsort(base, nbr_elements, width_bytes, compare_function); */ +/* void *base; */ +/* size_t nbr_elements, width_bytes; */ +/* int (*compare_function)(const void *, const void *); */ +/* */ +/* Sorts an array starting at base, of length nbr_elements, each */ +/* element of size width_bytes, ordered via compare_function, */ +/* which is called as (*compare_function)(ptr_to_element1, */ +/* ptr_to_element2) and returns < 0 if element1 < element2, */ +/* 0 if element1 = element2, > 0 if element1 > element2. */ +/* Most refinements are due to R. Sedgewick. See "Implementing */ +/* Quicksort Programs", Comm. ACM, Oct. 1978, and Corrigendum, */ +/* Comm. ACM, June 1979. */ +/******************************************************************/ + +#include <stddef.h> /* for size_t definition */ + +/* prototypes */ +void qsort(void *, size_t, size_t, + int (*)(const void *, const void *)); +void swap_chars(char *, char *, size_t); + +/* +** Compile with -DSWAP_INTS if your machine can access an int at an +** arbitrary location with reasonable efficiency. (Some machines +** cannot access an int at an odd address at all, so be careful.) +*/ + +#ifdef SWAP_INTS + void swap_ints(char *, char *, size_t); + #define SWAP(a, b) (swap_func((char *)(a), (char *)(b), width)) +#else + #define SWAP(a, b) (swap_chars((char *)(a), (char *)(b), size)) +#endif + +#define COMP(a, b) ((*comp)((void *)(a), (void *)(b))) + +#define T 7 /* subfiles of T or fewer elements will */ + /* be sorted by a simple insertion sort */ + /* Note! T must be at least 3 */ + +void qsort(void *basep, size_t nelems, size_t size, + int (*comp)(const void *, const void *)) +{ + char *stack[40], **sp; /* stack and stack pointer */ + char *i, *j, *limit; /* scan and limit pointers */ + size_t thresh; /* size of T elements in bytes */ + char *base; /* base pointer as char * */ + +#ifdef SWAP_INTS + size_t width; /* width of array element */ + void (*swap_func)(char *, char *, size_t); /* swap func pointer*/ + + width = size; /* save size for swap routine */ + swap_func = swap_chars; /* choose swap function */ + if ( size % sizeof(int) == 0 ) { /* size is multiple of ints */ + width /= sizeof(int); /* set width in ints */ + swap_func = swap_ints; /* use int swap function */ + } +#endif + + base = (char *)basep; /* set up char * base pointer */ + thresh = T * size; /* init threshold */ + sp = stack; /* init stack pointer */ + limit = base + nelems * size;/* pointer past end of array */ + for ( ;; ) { /* repeat until break... */ + if ( limit - base > thresh ) { /* if more than T elements */ + /* swap base with middle */ + SWAP((((limit-base)/size)/2)*size+base, base); + i = base + size; /* i scans left to right */ + j = limit - size; /* j scans right to left */ + if ( COMP(i, j) > 0 ) /* Sedgewick's */ + SWAP(i, j); /* three-element sort */ + if ( COMP(base, j) > 0 ) /* sets things up */ + SWAP(base, j); /* so that */ + if ( COMP(i, base) > 0 ) /* *i <= *base <= *j */ + SWAP(i, base); /* *base is pivot element */ + for ( ;; ) { /* loop until break */ + do /* move i right */ + i += size; /* until *i >= pivot */ + while ( COMP(i, base) < 0 ); + do /* move j left */ + j -= size; /* until *j <= pivot */ + while ( COMP(j, base) > 0 ); + if ( i > j ) /* if pointers crossed */ + break; /* break loop */ + SWAP(i, j); /* else swap elements, keep scanning*/ + } + SWAP(base, j); /* move pivot into correct place */ + if ( j - base > limit - i ) { /* if left subfile larger */ + sp[0] = base; /* stack left subfile base */ + sp[1] = j; /* and limit */ + base = i; /* sort the right subfile */ + } else { /* else right subfile larger*/ + sp[0] = i; /* stack right subfile base */ + sp[1] = limit; /* and limit */ + limit = j; /* sort the left subfile */ + } + sp += 2; /* increment stack pointer */ + } else { /* else subfile is small, use insertion sort */ + for ( j = base, i = j+size; i < limit; j = i, i += size ) + for ( ; COMP(j, j+size) > 0; j -= size ) { + SWAP(j, j+size); + if ( j == base ) + break; + } + if ( sp != stack ) { /* if any entries on stack */ + sp -= 2; /* pop the base and limit */ + base = sp[0]; + limit = sp[1]; + } else /* else stack empty, done */ + break; + } + } +} + +/* +** swap nbytes between a and b +*/ + +static void swap_chars(char *a, char *b, size_t nbytes) +{ + char tmp; + do { + tmp = *a; *a++ = *b; *b++ = tmp; + } while ( --nbytes ); +} + +#ifdef SWAP_INTS + +/* +** swap nints between a and b +*/ + +static void swap_ints(char *ap, char *bp, size_t nints) +{ + int *a = (int *)ap, *b = (int *)bp; + int tmp; + do { + tmp = *a; *a++ = *b; *b++ = tmp; + } while ( --nints ); +} + +#endif diff --git a/reference/C/CONTRIB/SNIP/rg_qsort.c2 b/reference/C/CONTRIB/SNIP/rg_qsort.c2 new file mode 100755 index 0000000..413ccab --- /dev/null +++ b/reference/C/CONTRIB/SNIP/rg_qsort.c2 @@ -0,0 +1,50 @@ +/* +** quicksort.c -- quicksort integer array +** +** public domain by Raymond Gardner 12/91 +*/ + +static void swap(int *a, int *b) +{ + register int t; + + t = *a; + *a = *b; + *b = t; +} + +void quicksort(int v[], unsigned n) +{ + unsigned i, j, ln, rn; + + while (n > 1) + { + swap(&v[0], &v[n/2]); + for (i = 0, j = n; ; ) + { + do + --j; + while (v[j] > v[0]); + do + ++i; + while (i < j && v[i] < v[0]); + if (i >= j) + break; + swap(&v[i], &v[j]); + } + swap(&v[j], &v[0]); + ln = j; + rn = n - ++j; + if (ln < rn) + { + quicksort(v, ln); + v += j; + n = rn; + } + else + { + quicksort(v + j, rn); + n = ln; + } + } +} diff --git a/reference/C/CONTRIB/SNIP/rg_rand.c b/reference/C/CONTRIB/SNIP/rg_rand.c new file mode 100755 index 0000000..578f70a --- /dev/null +++ b/reference/C/CONTRIB/SNIP/rg_rand.c @@ -0,0 +1,88 @@ +/* +** longrand() -- generate 2**31-2 random numbers +** +** public domain by Ray Gardner +** +** based on "Random Number Generators: Good Ones Are Hard to Find", +** S.K. Park and K.W. Miller, Communications of the ACM 31:10 (Oct 1988), +** and "Two Fast Implementations of the 'Minimal Standard' Random +** Number Generator", David G. Carta, Comm. ACM 33, 1 (Jan 1990), p. 87-88 +** +** linear congruential generator f(z) = 16807 z mod (2 ** 31 - 1) +** +** uses L. Schrage's method to avoid overflow problems +*/ + +#define a 16807 /* multiplier */ +#define m 2147483647L /* 2**31 - 1 */ +#define q 127773L /* m div a */ +#define r 2836 /* m mod a */ + +long nextlongrand(long seed) +{ + unsigned long lo, hi; + + lo = a * (long)(seed & 0xFFFF); + hi = a * (long)((unsigned long)seed >> 16); + lo += (hi & 0x7FFF) << 16; + if (lo > m) + { + lo &= m; + ++lo; + } + lo += hi >> 15; + if (lo > m) + { + lo &= m; + ++lo; + } + return (long)lo; +} + +static long randomnum = 1; + +long longrand(void) /* return next random long */ +{ + randomnum = nextlongrand(randomnum); + return randomnum; +} + +void slongrand(unsigned long seed) /* to seed it */ +{ + randomnum = seed ? (seed & m) : 1; /* nonzero seed */ +} + + +#ifdef TEST + +#include <stdio.h> +#include <stdlib.h> + +int main(int argc, char *argv[]) +{ + long reps, k, num; + unsigned long seed; + + reps = 10000; + seed = 1; + + /* + ** correctness test: after 10000 reps starting with seed 1, + ** result should be 1043618065 + */ + + if (argc > 1) + reps = atol(argv[1]); + if (argc > 2) + seed = atol(argv[2]); + + printf("seed %ld for %ld reps...\n", seed, reps); + slongrand(seed); + for (k = 0; k < reps; ++k) + num = longrand(); + printf("%ld\n", num); + + return 0; +} + +#endif diff --git a/reference/C/CONTRIB/SNIP/rg_ssort.c b/reference/C/CONTRIB/SNIP/rg_ssort.c new file mode 100755 index 0000000..b4a7675 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/rg_ssort.c @@ -0,0 +1,43 @@ +/* +** ssort() -- Fast, small, qsort()-compatible Shell sort +** +** by Ray Gardner, public domain 5/90 +*/ + +#include <stddef.h> + +void ssort (void *base, + size_t nel, + size_t width, + int (*comp)(const void *, const void *)) +{ + size_t wnel, gap, wgap, i, j, k; + char *a, *b, tmp; + + wnel = width * nel; + for (gap = 0; ++gap < nel;) + gap *= 3; + while ( gap /= 3 ) + { + wgap = width * gap; + for (i = wgap; i < wnel; i += width) + { + for (j = i - wgap; ;j -= wgap) + { + a = j + (char *)base; + b = a + wgap; + if ( (*comp)(a, b) <= 0 ) + break; + k = width; + do + { + tmp = *a; + *a++ = *b; + *b++ = tmp; + } while ( --k ); + if (j < wgap) + break; + } + } + } +} diff --git a/reference/C/CONTRIB/SNIP/rm_all.c b/reference/C/CONTRIB/SNIP/rm_all.c new file mode 100755 index 0000000..d1d6f0f --- /dev/null +++ b/reference/C/CONTRIB/SNIP/rm_all.c @@ -0,0 +1,222 @@ +/* +** Remove all files and (optionally) subdirectories +** +** public domain demo by Bob Stout +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <io.h> +#include <dos.h> +#include <ctype.h> + +#define LAST_CHAR(str) (str[strlen(str) - 1]) +#define MAX_PATH 80 + +#ifdef __TURBOC__ + #include <dir.h> + #include <io.h> + #define FAR far + #define find_1st(n,a,b) (findfirst((n),(b),(a))) + #define find_nxt(b) (findnext(b)) + #define find_t ffblk + #define name ff_name + #define attrib ff_attrib + #define _A_SUBDIR FA_DIREC +#else + #include <direct.h> + #include <stdarg.h> + #define FAR _far + #define find_1st(n,a,b) (_dos_findfirst((n),(a),(b))) + #define find_nxt(b) (_dos_findnext(b)) + + #ifndef FA_RDONLY + #define FA_RDONLY _A_RDONLY + #endif + + #ifndef FA_HIDDEN + #define FA_HIDDEN _A_HIDDEN + #endif + + #ifndef FA_SYSTEM + #define FA_SYSTEM _A_SYSTEM + #endif + + #if (defined(_MSC_VER) && (_MSC_VER >= 700)) || (defined(__SC__)) + // Make FP_xxx macros lvalues as in older versions + #undef FP_SEG + #undef FP_OFF + #define FP_SEG(fp) ((unsigned)((unsigned long)(fp) >> 16)) + #define FP_OFF(fp) ((unsigned)(fp && 0xffff)) + #endif + +#endif + +/* Select one of the following - remove() is ANSI */ + +#define rmfunc remove +/* #define rmfunc unlink */ + +#define show(s) fputs((s), stderr) + +typedef enum {ERROR = -1, SUCCESS, FALSE = 0, TRUE} LOGICAL; +LOGICAL recurse = FALSE, gobble = FALSE, ignore = FALSE; + +char *mask = "*.*"; + +/* +** Clean all files from a directory +*/ + +void clean_dir(char *path) +{ + char rmpath[MAX_PATH], *rmfile; + struct find_t fbuf; + unsigned attrib = (ignore) ? 0xff : 0; + + strcpy(rmpath, path); + if ('\\' != LAST_CHAR(rmpath)) + strcat(rmpath, "\\"); + rmfile = &rmpath[strlen(rmpath)]; + strcpy(rmfile, mask); + if (0 == find_1st(rmpath, attrib, &fbuf)) do + { + strcpy(rmfile, fbuf.name); + if (ignore) + { + union REGS regs; + struct SREGS sregs; + + regs.x.ax = 0x4300; + regs.x.dx = FP_OFF((char FAR *)rmpath); + segread(&sregs); + sregs.ds = FP_SEG((char FAR *)rmpath); + intdosx(®s, ®s, &sregs); + if (!regs.x.cflag) + { + regs.x.ax = 0x4301; + regs.x.cx &= ~(FA_RDONLY | FA_HIDDEN | FA_SYSTEM); + intdosx(®s, ®s, &sregs); + if (regs.x.cflag) + printf("unable to delete %s\n", rmpath); + } + } + rmfunc(rmpath); + printf("deleting %s\n", rmpath); + } while (0 == find_nxt(&fbuf)); +} + +/* +** Process directories +*/ + +void do_dir(char *path) +{ + char search[MAX_PATH], new[MAX_PATH]; + struct find_t ff; + + strcpy(search, path); + if ('\\' != LAST_CHAR(search)) + strcat(search, "\\"); + strcat(search, "*.*"); + if (SUCCESS == find_1st(search, 0xff, &ff)) do + { + if (ff.attrib & _A_SUBDIR && '.' != *ff.name) + { + strcpy(new, path); + if ('\\' != LAST_CHAR(new)) + strcat(new, "\\"); + strcat(new, ff.name); + do_dir(new); + } + } while (SUCCESS == find_nxt(&ff)); + clean_dir(path); + if (gobble) + rmdir(path); +} + +/* +** Tell 'em they messed up +*/ + +void usage(LOGICAL errstat) +{ + if (errstat) + fputc('\a', stderr); + show("Usage: RM_ALL directory [...directory] [-eFNAME.EXT] [-rgi?]\n"); + show("switches: -eFNAME.EXT Remove only files matching mask " + "(default is \"-e*.*\")\n"); + show(" -r Recurse subdirectories\n"); + show(" -g Gobble (delete) empty subdirectories\n"); + show(" -i Ignore special file attributes " + "(CAUTION!)\n"); + show(" -? Display help (this message)\n"); + exit(errstat); +} + +/* +** RM_ALL - Deletes all files and (optionally) subdirectories +*/ + +int main(int argc, char *argv[]) +{ + int i, j; + LOGICAL found_dir = FALSE; + void (*clean_func)(char *) = clean_dir; + + for (i = 1; i < argc; ++i) /* Check for switches */ + { + if (NULL == strchr("-/", *argv[i])) + continue; /* Assume it's a filename */ + for (j = 1; argv[i][j] ; ++j) /* Traverse nested switches */ + { + switch (toupper(argv[i][j])) + { + case 'R': + clean_func = do_dir; + break; + + case 'G': + gobble = TRUE; + break; + + case 'I': + ignore = TRUE; + break; + + case '?': + puts("***help***"); + usage(FALSE); + break; + + case 'E': + if (0 == strlen(&argv[i][++j])) + { + puts("***no file***"); + usage(ERROR); /* Oops */ + } + mask = strupr(&argv[i][j]); + j += strlen(&argv[i][j]) - 1; /* End of switch */ + break; + + default: + puts("***default***"); + usage(ERROR); + } + } + } + for (i = 1; i < argc; ++i) /* Scan filenames */ + { + if (strchr("/-", *argv[i])) + continue; + found_dir = TRUE; + clean_func(argv[i]); + } + if (!found_dir) + { + puts("***not found***"); + usage(TRUE); + } + else return 0; +} diff --git a/reference/C/CONTRIB/SNIP/rmallws.c b/reference/C/CONTRIB/SNIP/rmallws.c new file mode 100755 index 0000000..84ca8a0 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/rmallws.c @@ -0,0 +1,28 @@ +/* +** Originally published as part of the MicroFirm Function Library +** +** Copyright 1986, S.E. Margison +** Copyright 1989, Robert B.Stout +** +** Subset version released to the public domain, 1991 +** +** remove all whitespace from a string +*/ + +#include <stdio.h> +#include <ctype.h> + +#define NUL '\0' + +char *rmallws(char *str) +{ + char *obuf, *nbuf; + + for (obuf = str, nbuf = str; *obuf && obuf; ++obuf) + { + if (!isspace(*obuf)) + *nbuf++ = *obuf; + } + *nbuf = NUL; + return str; +} diff --git a/reference/C/CONTRIB/SNIP/rmlead.c b/reference/C/CONTRIB/SNIP/rmlead.c new file mode 100755 index 0000000..e3e3c18 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/rmlead.c @@ -0,0 +1,26 @@ +/* +** Originally published as part of the MicroFirm Function Library +** +** Copyright 1986, S.E. Margison +** Copyright 1989, Robert B.Stout +** +** Subset version released to the public domain, 1991 +** +** remove leading whitespace from a string +*/ + +#include <ctype.h> +#include <string.h> + +#define NUL '\0' + +char *rmlead(char *str) +{ + char *obuf; + + for (obuf = str; obuf && *obuf && isspace(*obuf); ++obuf) + ; + if (str != obuf) + strcpy(str, obuf); + return str; +} diff --git a/reference/C/CONTRIB/SNIP/rmtrail.c b/reference/C/CONTRIB/SNIP/rmtrail.c new file mode 100755 index 0000000..d95c317 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/rmtrail.c @@ -0,0 +1,31 @@ +/* +** Originally published as part of the MicroFirm Function Library +** +** Copyright 1986, S.E. Margison +** Copyright 1989, Robert B.Stout +** +** Subset version released to the public domain, 1991 +** +** remove trailing whitespace from a string +*/ + +#include <string.h> +#include <ctype.h> + +#define NUL '\0' + +char *rmtrail(char *str) +{ + int i; + + if (0 != (i = strlen(str))) + { + while (--i >= 0) + { + if (!isspace(str[i])) + break; + } + str[++i] = NUL; + } + return str; +} diff --git a/reference/C/CONTRIB/SNIP/rndmize.c b/reference/C/CONTRIB/SNIP/rndmize.c new file mode 100755 index 0000000..6d6cfe0 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/rndmize.c @@ -0,0 +1 @@ +srand( ((unsigned int)time(NULL)) | 1); diff --git a/reference/C/CONTRIB/SNIP/roman.c b/reference/C/CONTRIB/SNIP/roman.c new file mode 100755 index 0000000..b65d6a4 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/roman.c @@ -0,0 +1,97 @@ +/* + * + * ROMAN.C - Converts integers to Roman numerals + * + * Written by: Jim Walsh + * + * Compiler : Microsoft QuickC v2.5 + * + * This Program Is Released To The Public Domain + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +int main( int argc, char *argv[] ) +{ + int value, dvalue; + char roman[80]; + roman[0] = '\0'; + if( argc == 2 ) + value = atoi( argv[1] ); + else + { + printf( "\nEnter an integer value: " ); + scanf( "%d", &value ); + } + dvalue = value; + while( value >= 1000 ) + { + strcat( roman, "M" ); + value -= 1000; + } + if( value >= 900 ) + { + strcat( roman, "CM" ); + value -= 900; + } + while( value >= 500 ) + { + strcat( roman, "D" ); + value -= 500; + } + if( value >= 400 ) + { + strcat( roman, "CD" ); + value -= 400; + } + while( value >= 100 ) + { + strcat( roman, "C" ); + value -= 100; + } + if( value >= 90 ) + { + strcat( roman, "XC" ); + value -= 90; + } + while( value >= 50 ) + { + strcat( roman, "L" ); + value -= 50; + } + if( value >= 40 ) + { + strcat( roman, "XL" ); + value -= 40; + } + while( value >= 10 ) + { + strcat( roman, "X" ); + value -= 10; + } + if( value >= 9 ) + { + strcat( roman, "IX" ); + value -= 9; + } + while( value >= 5 ) + { + strcat( roman, "V" ); + value -= 5; + } + if( value >= 4 ) + { + strcat( roman, "IV" ); + value -= 4; + } + while( value > 0 ) + { + strcat( roman, "I" ); + value--; + } + printf( "\n%d = %s\n", dvalue, roman ); + return(0); +} diff --git a/reference/C/CONTRIB/SNIP/round.h b/reference/C/CONTRIB/SNIP/round.h new file mode 100755 index 0000000..6736c06 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/round.h @@ -0,0 +1,11 @@ +/* +** rounding macros by Dave Knapp & Thad Smith +*/ + +/* round to integer */ + +#define iround(x) floor((x)+0.5) + +/* round number n to d decimal points */ + +#define fround(n,d) (floor((n)*pow(10.,(d))+.5)/pow(10.,(d))) diff --git a/reference/C/CONTRIB/SNIP/rtlftrul.txt b/reference/C/CONTRIB/SNIP/rtlftrul.txt new file mode 100755 index 0000000..b0b5c10 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/rtlftrul.txt @@ -0,0 +1,140 @@ +Organization: KFW Corporation, Newbury Park, CA +Message-ID: <1990Jul16.195111.5976@kfw.COM> +Newsgroups: comp.lang.c + +I've received several mail messages since offering to explain the +right-left rule via e-mail, so I've decided to post. For those of +you who already know this or don't care, quit now (this is a little +long). + +The "right-left" rule is a completely regular rule for deciphering C +declarations. It can also be useful in creating them. + +First, symbols. Read + + * as "pointer to" + [] as "array of" + () as "function returning" + +as you encounter them in the declaration. + +STEP 1 +------ +Find the identifier. This is your starting point. Then say to yourself, +"identifier is". You've started your declaration. + +STEP 2 +------ +Look at the symbols on the right of the identifier. If, say, you find "()" +there, then you know that this is the declaration for a function. So you +would then have "identifier is function returning". Or if you found a +"[]" there, you would say "identifier is array of". Continue right until +you run out of symbols *OR* hit a *right* parenthesis ")". (If you hit a +left parenthesis, that's the beginning of a () symbol, even if there +is stuff in between the parentheses. More on that below.) + +STEP 3 +------ +Look at the symbols to the left of the identifier. If it is not one of our +symbols above (say, something like "int"), just say it. Otherwise, translate +it into English using that table above. Keep going left until you run out of +symbols *OR* hit a *left* parenthesis "(". + +Now repeat steps 2 and 3 until you've formed your declaration. Here are some +examples: + + int *p[]; + +1) Find identifier. int *p[]; + ^ + "p is" + +2) Move right until out of symbols or left parenthesis hit. + int *p[]; + ^^ + "p is array of" + +3) Can't move right anymore (out of symbols), so move left and find: + int *p[]; + ^ + "p is array of pointer to" + +4) Keep going left and find: + int *p[]; + ^^^ + "p is array of pointer to int". + +Another example: + + int *(*func())(); + +1) Find the identifier. int *(*func())(); + ^^^^ + "func is" + +2) Move right. int *(*func())(); + ^^ + "func is function returning" + +3) Can't move right anymore because of the right parenthesis, so move left. + int *(*func())(); + ^ + "func is function returning pointer to" + +4) Can't move left anymore because of the left parenthesis, so keep going + right. int *(*func())(); + ^^ + "func is function returning pointer to function returning" + +5) Can't move right anymore because we're out of symbols, so go left. + int *(*func())(); + ^ + "func is function returning pointer to function returning pointer to" + +6) And finally, keep going left, because there's nothing left on the right. + int *(*func())(); + ^^^ + "func is function returning pointer to function returning pointer to int". + +As you can see, this rule can be quite useful. You can also use it to +sanity check yourself while you are creating declarations, and to give +you a hint about where the put the next symbol and whether parentheses +are required. + +Some declarations look much more complicated than they are due to array +sizes and argument lists in prototype form. If you see "[3]", that's +read as "array (size 3) of...". If you see "(char *,int)" that's read +as "function expecting (char *,int) and returning...". Here's a fun +one: + + int (*(*fun_one)(char *,double))[9][20]; + +I won't go through each of the steps to decipher this one. It's: + + "fun_one is pointer to function expecting (char *,double) and + returning pointer to array (size 9) of array (size 20) of int." + +As you can see, it's not as complicated if you get rid of the array sizes +and argument lists: + + int (*(*fun_one)())[][]; + +You can decipher it that way, and then put in the array sizes and argument +lists later. + +Some final words: + +It is quite possible to make illegal declarations using this rule, +so some knowledge of what's legal in C is necessary. For instance, +if the above had been: + + int *((*fun_one)())[][]; + +it would have been "fun_one is pointer to function returning array of array of + ^^^^^^^^^^^^^^^^^^^^^^^^ +pointer to int". Since a function cannot return an array, but only a +pointer to an array, that declaration is illegal. + +Will +will@kfw.com +uunet!charyb!will diff --git a/reference/C/CONTRIB/SNIP/scaldate.c b/reference/C/CONTRIB/SNIP/scaldate.c new file mode 100755 index 0000000..ca0f00d --- /dev/null +++ b/reference/C/CONTRIB/SNIP/scaldate.c @@ -0,0 +1,49 @@ +/* +** scalar date routines -- public domain by Ray Gardner +** These will work over the range 1/01/01 thru 14699/12/31 +*/ + +#include "scaldate.h" + +int isleap (unsigned yr) +{ + return yr % 400 == 0 || (yr % 4 == 0 && yr % 100 != 0); +} + +static unsigned months_to_days (unsigned month) +{ + return (month * 3057 - 3007) / 100; +} + +static long years_to_days (unsigned yr) +{ + return yr * 365L + yr / 4 - yr / 100 + yr / 400; +} + +long ymd_to_scalar (unsigned yr, unsigned mo, unsigned day) +{ + long scalar; + scalar = day + months_to_days(mo); + if ( mo > 2 ) /* adjust if past February */ + scalar -= isleap(yr) ? 1 : 2; + yr--; + scalar += years_to_days(yr); + return scalar; +} + +void scalar_to_ymd (long scalar, unsigned *yr, unsigned *mo, unsigned *day) +{ + unsigned n; /* compute inverse of years_to_days() */ + + for ( n = (unsigned)((scalar * 400L) / 146097); years_to_days(n) < scalar;) + n++; /* 146097 == years_to_days(400) */ + *yr = n; + n = (unsigned)(scalar - years_to_days(n-1)); + if ( n > 59 ) { /* adjust if past February */ + n += 2; + if ( isleap(*yr) ) + n -= n > 62 ? 1 : 2; + } + *mo = (n * 100 + 3007) / 3057; /* inverse of months_to_days() */ + *day = n - months_to_days(*mo); +} diff --git a/reference/C/CONTRIB/SNIP/scaldate.h b/reference/C/CONTRIB/SNIP/scaldate.h new file mode 100755 index 0000000..6fa7dbb --- /dev/null +++ b/reference/C/CONTRIB/SNIP/scaldate.h @@ -0,0 +1,27 @@ +/* +** scalar date routines -- public domain by Ray Gardner +** These will work over the range 1/01/01 thru 14699/12/31 +*/ + +/* +** Define ISO to be 1 for ISO (Mon-Sun) calendars +** +** ISO defines the first week with 4 or more days in it to be week #1. +*/ + +#ifndef ISO + #define ISO 0 +#endif + +#if (ISO != 0 && ISO != 1) + #error ISO must be set to either 0 or 1 +#endif + +int isleap (unsigned yr); +long ymd_to_scalar (unsigned yr, unsigned mo, unsigned day); +void scalar_to_ymd (long scalar, unsigned *yr, unsigned *mo, unsigned *day); +int dow(unsigned yr, unsigned mo, unsigned day); +int valiDate(unsigned yr, unsigned mo, unsigned day); +int dow(unsigned yr, unsigned mo, unsigned day); +int daynum(int year, int month, int day); +int weeknum(int year, int month, int day); diff --git a/reference/C/CONTRIB/SNIP/scanfrac.c b/reference/C/CONTRIB/SNIP/scanfrac.c new file mode 100755 index 0000000..87b623e --- /dev/null +++ b/reference/C/CONTRIB/SNIP/scanfrac.c @@ -0,0 +1,119 @@ +/* function scanfrac - scan an input string for a numeric value. +** +** Written in ANSI C and contributed to the public domain by +** Thad Smith III, Boulder, CO. August 5, 1991 +*/ + +/******************************************************************* +** scanfrac() scans an input string for a numeric value, which can +** be specified as: +** 1. an integer, 5 +** 2. a floating point value, 5.1 +** 3. a fraction, or 3/4 +** 4. a mixed fraction. 5 3/4 or 5-3/4 +** +** Conditions: +** 1. Preceeding whitespace is allowed. +** 2. The input number may be signed. +** 3. The fractional part of a mixed fraction (but not pure fraction) +** must be less than 1. +** 4. The numerator and denominator of a fraction or mixed fraction +** must be less than 2^31. +** +** Parameters: +** 1. Input buffer containing value. +** 2. Pointer to double to receive return value. +** +** Return status: +** 0 = OK, value returned in f, +** 1 = bad input format, +** 2 = can't allocate memory +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <math.h> + +int scanfrac (const char buf[], double *f) +{ + char *tbuf = malloc (strlen(buf) +2); /* input + terminator */ + static char term[] = "\a"; /* terminator flag */ + char t1,t2,t3; /* separator chars */ + char sign; /* possible sign */ + int nc; /* # conversions */ + long int b,c; /* 2nd & 3rd inputs */ + + if (!tbuf) /* couldn't allocate memory */ + return 2; + + /* Copy the input to a temporary buffer and append a terminator + ** character. This terminator is used to determine whether the + ** scanning of the input field by sscanf() was terminated by end + ** of input or by an invalid character. If terminated properly, + ** the terminator character picked up in t1, t2, or t3. + */ + + strcat (strcpy(tbuf, buf), term); /* input + term flag */ + nc = sscanf (tbuf, " %lf%c %ld %c %ld %c", + f,&t1,&b,&t2,&c,&t3); + free (tbuf); + + switch (nc) /* number of sscanf() conversions */ + { + case 2: /* single floating value: a */ + if (t1 == *term) return 0; + break; + case 4: /* pure fraction: a/b */ + if (t1 == '/' && t2 == *term && fmod (*f,1.0) == 0.0 && b > 0) + { + *f /= b; + return 0; + } + break; + case 6: /* mixed fraction: a b/c or a-b/c */ + if ((t1 == ' ' || t1 == '-') && t2 == '/' && t3 == *term && + fmod (*f,1.0) == 0.0 && b >= 0 && c > b) + { + /* get first non-blank character so that + ** -0 b/c will be neg + */ + +#ifdef __ZTC__ /* fix for missing const in sscanf() declaration */ + sscanf ((char*)buf, " %c", &sign); +#else + sscanf (buf, " %c", &sign); +#endif + if (sign == '-') + *f -= (double)b/c; + else *f += (double)b/c; + return 0; + } + } + return 1; +} + +/* This is a simple test driver. It should be omitted before +** placing scanfrac() into a library. +*/ + +main () +{ + char buf[80]; + double f; + int stat; + + printf ("Enter 999. or generate EOF to stop\n"); + do + { + printf ("Enter value: "); + if (! gets (buf)) + { + printf ("EOF detected. Aborting.\n"); + return 1; + } + stat = scanfrac (buf, &f); + printf ("\nStat = %d, value = %f\n", stat, f); + } while ( f != 999.); + return 0; +} diff --git a/reference/C/CONTRIB/SNIP/scrnmacs.h b/reference/C/CONTRIB/SNIP/scrnmacs.h new file mode 100755 index 0000000..7caa4a4 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/scrnmacs.h @@ -0,0 +1,92 @@ +/* +** Macros for managing direct video writes by Jerry Houston +** +** prototypes for SCROLL.C and VIDPORT.C functions added by Bob Stout +*/ + +#if defined(__TURBOC__) + #define FAR far +#else + #define FAR _far +#endif + +#ifndef MK_FP + #define MK_FP(seg,off) ((void far *)(((long)(seg) << 16)|(unsigned)(off))) +#endif + +/* +** Text screen scrolling function from SCROLL.C in SNIPPETS +*/ + +#define SCROLL_UP 0 +#define SCROLL_DN 1 + +void scroll(int direction, + int num_lines, + int vattrib, + int ulrow, + int ulcomumn, + int lrrow, + int lrcolumn); + +/* +** Functions in VIDPORT.C in SNIPPETS +*/ + +void GotoXY(int col, int row); +void ClrScrn(int vattrib); +void GetCurPos(int *col, int *row); +int GetCurAtr(void); +void ClrEol(void); +void ClrEop(void); +void Repaint(int vattrib); + +#if !defined(COLORMODE) + #define COLORMODE ((*(char FAR *)0x0449) != 7) + #define EXT_KBD (*(char FAR *)0x0496 & 16) + #define VIDPAGE (*((unsigned char far *)0x0462)) + #define ROWSIZE (*(int FAR *)0x044A) + #define SCANLINES ((int)*(char FAR*)0x0461) + #define SCRBUFF ((unsigned FAR *)((COLORMODE)?0xB8000000:0xB0000000)) + #define SCREENSEG ((unsigned)((COLORMODE)?0xB800:0xB000)) + #define SCREENSIZE ((*(int FAR *)0x044C) >> 1) + #define SCREENCOLS (*(int FAR *)0x044A) + #define SCREENROWS ((*(char FAR *)0x0484)?1+(*(char FAR *)0x0484):25) +#endif + +/* + COLORMODE = true/false, are we using color? + EXT_KBD = true/false, extended keyboard in use? + VIDPAGE = current video page in use + SCANLINES = number of scan lines in a character. + SCRBUFF = returns B800:0000 if using color, B000:0000 if mono. + SCREENSEG = when you just need the segment portion. + SCREENSIZE = number of (2-byte) cells required to save screen. + SCREENCOLS = number of columns, often 80. + SCREENROWS = number of rows, usually defaults to 25. +*/ + +/* +** colors -- Use as is for foreground colors +** For background, shift left by 4 and OR with +** foreground and possible video attributes +*/ + +#define BLACK 0 +#define BLUE 1 +#define GREEN 2 +#define CYAN 3 +#define RED 4 +#define MAGENTA 5 +#define BROWN 6 +#define WHITE 7 +#define GRAY 8 +#define LTBLUE 9 +#define LTGREEN 10 +#define LTCYAN 11 +#define LTRED 12 +#define LTMAGENTA 13 +#define YELLOW 14 +#define HIWHITE 15 /* hi-intensity white */ + +#define BG_(a) (((a) & 0x7f) << 4) diff --git a/reference/C/CONTRIB/SNIP/scrnpick.c b/reference/C/CONTRIB/SNIP/scrnpick.c new file mode 100755 index 0000000..a106005 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/scrnpick.c @@ -0,0 +1,58 @@ +/* program: mousword.c + * programmer: Ray L. McVay + * date: 20 Oct 1988 + * modified: 15 Feb 93 by Bob Stout to use Bob Jarvis' MOUSE.H and MOUSE.C + * + * Demonstration of picking "words" off a text mode PC screen using a mouse. + * Submitted to the C_ECHO and placed in the public domain, 7 Jun 1992. + */ + +#include <stdio.h> +#include <stdlib.h> +#include "mouse.h" + +char word[80]; +int FAR *scrn = (int FAR *)0xb8000000L; /* See VIO.H for a better way */ + +void getword(char *, int, int); + +main(void) +{ + int done, b, x, y; + + ms_reset(&b); /* reset */ + ms_show_cursor(); + for (done = 0; !done; ) + { + b = ms_get_mouse_pos(&x, &y); + if (b == 1) + { + ms_hide_cursor(); + getword(word, x/8, y/8); + do + { + b = ms_get_mouse_pos(&x, &y); + } while (b); + if (*word) + printf("{%s}\n", word); + ms_show_cursor(); + } + else if (b > 1) + done = 1; + } + ms_reset(&b); + return 0; +} + +void getword(char *w, int x, int y) +{ + int txs, txe, ci; + + for (txs = x; (txs >= 0) && ((scrn[80 * y + txs] & 255) != 32); txs--) + scrn[80 * y + txs] = (scrn[80 * y + txs] & 255) | 0x7000; + for (txe = x; (txe < 80) && ((scrn[80 * y + txe] & 255) != 32); txe++) + scrn[80 * y + txe] = (scrn[80 * y + txe] & 255) | 0x7000; + for (ci = txs + 1; ci < txe; ci++) + *w++ = (char)scrn[80 * y + ci]; + *w = 0; +} diff --git a/reference/C/CONTRIB/SNIP/scrnsave.c b/reference/C/CONTRIB/SNIP/scrnsave.c new file mode 100755 index 0000000..9d65e80 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/scrnsave.c @@ -0,0 +1,79 @@ +/* +** SCRNSAVE.C - Save and restore text screen portably +** +** public domain demo by Bob Stout +*/ + +#include <stdlib.h> + +/* +** Stuff from SNIPPETS courtesy of Jim Nutt +** +** Notes: VIOopen() is called redundantly to assure that the video +** information is always initialized. These multiple calls are benign. +** +** Because of using VIO.OBJ, this *must* be compiled in large model! +*/ + +#include "vio.h" + +/* +** Save the current text screen +** +** Arguments: None +** +** Returns: Pointer to saved screen buffer, NULL if insufficient heap +*/ + +unsigned short *savescreen(void) +{ + unsigned short *vbuf; + + VIOopen(); + if (NULL == (vbuf = malloc(VIOcolumns() * VIOrows() * 2))) + return NULL; + VIOgetra(0, 0, VIOcolumns() - 1, VIOrows() - 1, (int _far *)vbuf); + return vbuf; +} + +/* +** Restore a screen previously saved by savescreen() +** +** Arguments: Buffer containing the screen to restore +** +** Returns: Nothing +** +** WARNING: No error checking done to verify same screen size and mode! +*/ + +void restorescreen(unsigned short *vbuf) +{ + VIOopen(); + VIOputr(0, 0, VIOcolumns(), VIOrows(), (int _far *)vbuf); + free(vbuf); +} + +#ifdef TEST + +#include <stdio.h> +#include <conio.h> + +int main(void) +{ + unsigned short *vbuf; + + VIOopen(); + if (NULL == (vbuf = savescreen())) + { + puts("Unable to save screen"); + return EXIT_FAILURE; + } + VIOclear(0, 0, VIOcolumns(), VIOrows()); + puts("Hit any key to exit"); + getch(); + restorescreen(vbuf); + VIOclose(); + return EXIT_SUCCESS; +} + +#endif /* TEST */ diff --git a/reference/C/CONTRIB/SNIP/scroll.c b/reference/C/CONTRIB/SNIP/scroll.c new file mode 100755 index 0000000..e5a94f7 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/scroll.c @@ -0,0 +1,47 @@ +/*--------------------------[ scroll ]--------------------------*/ +/* Scroll the active page up or down a number of lines */ +/* Public domain code by Jeff Dunlop: */ +/*--------------------------------------------------------------*/ +/* input: */ +/* dx = direction */ +/* num_lines = number of lines to scroll, 0 = clear coords */ +/* attr = attribute of blank line(s) */ +/* y1, x1, y2, x2 = corner coordinates of scroll window */ +/* local: */ +/* regs = register union for ISR */ +/*--------------------------------------------------------------*/ + +#include <dos.h> +#include "scrnmacs.h" + +void scroll(int direction, + int num_lines, + int vattrib, + int ulrow, + int ulcomumn, + int lrrow, + int lrcolumn) +{ + union REGS regs; + + /* + BH = attribute to be used on blank line + CH = row of upper left corner of scroll window + CL = column of upper left corner of scroll window + DH = row of lower right corner of scroll window + DL = column of lower right corner of scroll window + */ + + regs.h.al = (unsigned char)num_lines; + regs.h.bh = (unsigned char)vattrib; + regs.h.ch = (unsigned char)ulrow; + regs.h.cl = (unsigned char)ulcomumn; + regs.h.dh = (unsigned char)lrrow; + regs.h.dl = (unsigned char)lrcolumn; + + if (direction == SCROLL_UP) + regs.h.ah = 0x06; + else regs.h.ah = 0x07; + + int86(0x10, ®s, ®s); +} diff --git a/reference/C/CONTRIB/SNIP/setenvar.c b/reference/C/CONTRIB/SNIP/setenvar.c new file mode 100755 index 0000000..e2271d5 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/setenvar.c @@ -0,0 +1,155 @@ +/* +** SETENVAR.C - Program which sets the DOS master environment upon exit +** +** Original Copyright 1988-1991 by Bob Stout as part of +** the MicroFirm Function Library (MFL) +** +** This subset version is functionally identical to the +** version originally published by the author in Tech Specialist +** magazine and is hereby donated to the public domain. +*/ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <conio.h> +#include <dos.h> + +#if !defined(__ZTC__) && !defined(__TURBOC__) + #define MK_FP(seg,offset) \ + ((void far *)(((unsigned long)(seg)<<16) | (unsigned)(offset))) + #define peek(s,o) (*((unsigned far *)(MK_FP(s,o)))) + #define poke(s,o,w) (*((unsigned far *)(MK_FP(s,o)))=(w)) +#endif + +#define SUCCESS 0 +#define ERROR -1 + +static unsigned head, tail, start, end; +static int idx = 0; +static unsigned keystack[16][2]; + +/* +** ungetkey() +** +** Stuffs characters into the keyboard buffer. +** +** Parameters: 1 - Extended character to stuff +** +** Returns: SUCCESS or EOF +** +** Note: This function assumes that the keyboard buffer is in +** the normal (for IBM) location of 40:1E. +** +*/ + +int ungetkey(unsigned key) +{ + int count; + +#ifdef __ZTC__ + peek(0x40, 0x1a, &head, sizeof(unsigned)); + peek(0x40, 0x1c, &tail, sizeof(unsigned)); + peek(0x40, 0x80, &start, sizeof(unsigned)); + peek(0x40, 0x82, &end, sizeof(unsigned)); +#else + head = peek(0x40, 0x1a); + tail = peek(0x40, 0x1c); + start = peek(0x40, 0x80); + end = peek(0x40, 0x82); +#endif + count = tail - head; + if (0 > count) + count += (16 * sizeof(unsigned)); + count >>= 1; + + if (15 > count) + { +#ifdef __ZTC__ + peek(0x40, tail, &keystack[idx][0], sizeof(unsigned)); +#else + keystack[idx][0] = peek(0x40, tail); +#endif + keystack[idx][1] = tail; +#ifdef __ZTC__ + poke(0x40, tail, &key, sizeof(unsigned)); +#else + poke(0x40, tail, key); +#endif + tail += sizeof(unsigned); + if (end <= tail) + tail = start; +#ifdef __ZTC__ + poke(0x40, 0x1c, &tail, sizeof(unsigned)); +#else + poke(0x40, 0x1c, tail); +#endif + return key; + } + return EOF; +} + +/* +** KB_stuff() +** +** Stuffs strings into the keyboard buffer. +** +** Parameters: 1 - String to stuff +** +** Returns: SUCCESS if successful +** ERROR in case of error, plus beyboard buffer is +** restored +** +** Note: This function assumes that the keyboard buffer is in +** the normal (for IBM) location of 40:1E. +*/ + +int KB_stuff(char *str) +{ + int ercode = SUCCESS; + + idx = 0; + while (*str) + { + if (EOF == ungetkey((unsigned)(*str++))) + { + while (0 <= --idx) + { + tail = keystack[idx][1]; +#ifdef __ZTC__ + poke(0x40, tail, &keystack[idx][0], + sizeof(unsigned)); +#else + poke(0x40, tail, keystack[idx][0]); +#endif + } +#ifdef __ZTC__ + poke(0x40, 0x1c, &tail, sizeof(unsigned)); +#else + poke(0x40, 0x1c, tail); +#endif + ercode = ERROR; + break; + } + else ++idx; + } + idx = 0; + return ercode; +} + +void main(int argc, char *argv[]) +{ + FILE *bfile; + + if (3 > argc) + { + puts("\aUsage: SETENVAR envar datum"); + abort(); + } + bfile = fopen("$TMP$.BAT", "w"); + fprintf(bfile, "SET %s=%s\ndel $tmp$.bat\x1a", argv[1], argv[2]); + fclose(bfile); + while (kbhit()) + getch(); + KB_stuff("$tmp$\r"); +} diff --git a/reference/C/CONTRIB/SNIP/setimeto.c b/reference/C/CONTRIB/SNIP/setimeto.c new file mode 100755 index 0000000..3d32827 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/setimeto.c @@ -0,0 +1,64 @@ +/* +** SETIMETO.C - Set the timestamp of one file to match another. +** +** public domain demo by Bob Stout +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <dos.h> +#include <io.h> +#include <fcntl.h> + +#ifdef __ZTC__ + #define GETFTIME dos_getftime + #define SETFTIME dos_setftime +#else + #define GETFTIME _dos_getftime + #define SETFTIME _dos_setftime +#endif + +int main(int argc, char *argv[]) +{ + int fd0, fd1; + +#ifdef __TURBOC__ + struct ftime Ftime; +#else + unsigned date, time; +#endif + + if (3 > argc) + { + puts("Usage: SETIMETO old_filename new_filename"); + return EXIT_FAILURE; + } + + if (-1 == (fd0 = open(argv[1], O_RDONLY))) + { + printf("Unable to open %s\n", argv[1]); + return EXIT_FAILURE; + } + +#ifdef __TURBOC__ /* Save the time/date */ + getftime(fd0, &Ftime); +#else + GETFTIME(fd0, &date, &time); +#endif + + if (-1 == (fd1 = open(argv[2], O_WRONLY))) + { + printf("Unable to open %s\n", argv[2]); + return EXIT_FAILURE; + } + +#ifdef __TURBOC__ /* Set the time/date */ + setftime(fd1, &Ftime); +#else + SETFTIME(fd1, date, time); +#endif + + close(fd0); + close(fd1); + return EXIT_SUCCESS; +} diff --git a/reference/C/CONTRIB/SNIP/setvol.c b/reference/C/CONTRIB/SNIP/setvol.c new file mode 100755 index 0000000..d31483b --- /dev/null +++ b/reference/C/CONTRIB/SNIP/setvol.c @@ -0,0 +1,222 @@ +/* +** SETVOL.C - set, change, or kill a disk volume label +** +** public domain demo by Bob Stout +** DOS 5 enhancements suggested by Keith Beedle +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#include <dos.h> +#include <io.h> +#include "portable.h" /* Also in SNIPPETS */ + +#define NUL '\0' + +#if defined(__TURBOC__) + #pragma option -a- + #include <dir.h> + #include <io.h> + #define _A_VOLID FA_LABEL + #define _far far +#else + #include <direct.h> + #if defined(__ZTC__) + #pragma ZTC align 1 + #else /* MSC/QC/WATCOM/METAWARE */ + #pragma pack(1) + #endif + struct fcb { + char fcb_drive; + char fcb_name[8]; + char fcb_ext[3]; + short fcb_curblk; + short fcb_recsize; + long fcb_filsize; + short fcb_date; + char fcb_resv[10]; + char fcb_currec; + long fcb_random; + }; + + struct xfcb { + char xfcb_flag; + char xfcb_resv[5]; + char xfcb_attr; + struct fcb xfcb_fcb; + }; +#endif + +#include "dos5boot.h" /* SNIPPETS file with DOS 5 boot record structure */ + +/* +** NOTE: The following use functions in four other SNIPPETS files, +** ABSDISK.ASM, ABSDISKC.C, DRVALID.C, and PUSHDIR.C +*/ + +int AbsDiskRead(unsigned short, size_t, size_t, void *); +int AbsDiskWrite(unsigned short, size_t, size_t, void *); +int getdrv(void); +int PushDir(char *); +int PopDir(void); + +/* +** Erase an existing volume label +*/ + +void vol_kill(char *fname) +{ + union REGS regs; + struct SREGS sregs; + struct xfcb buf; + + /* Parse the filename into an FCB */ + + segread(&sregs); + regs.h.ah = 0x29; + regs.h.al = 0; + regs.x.si = (unsigned)fname; + regs.x.di = (unsigned)&buf.xfcb_fcb; + sregs.es = sregs.ds; + intdosx(®s, ®s, &sregs); + + /* Volume labels require extended FCB's */ + + buf.xfcb_flag = 0xff; + buf.xfcb_attr = _A_VOLID; + + /* Delete the old label */ + + regs.h.ah = 0x13; + regs.x.dx = (unsigned)&buf; + intdos(®s, ®s); +} + +/* +** Create a new volume label +*/ + +void setvol(char *label) +{ + char new_label[13]; /* name + ext + '.' + NUL */ + struct xfcb buf; + union REGS regs; + struct SREGS sregs; + const char pattern[] = "????????"; + char _far *dta; + + /* + ** Change to root directory. + */ + + PushDir("\\"); + + /* If drive is already labeled, remove it */ + + segread(&sregs); + regs.h.ah = 0x2f; + intdosx(®s, ®s, &sregs); + dta = MK_FP(sregs.es, regs.x.bx); + + buf.xfcb_flag = 0xff; + buf.xfcb_attr = _A_VOLID; + buf.xfcb_fcb.fcb_drive = 0; + memcpy(buf.xfcb_fcb.fcb_name, pattern, 8); + memcpy(buf.xfcb_fcb.fcb_ext, pattern, 3); + + regs.h.ah = 0x11; + regs.x.dx = (unsigned)&buf; + intdos(®s, ®s); + + if (0 == regs.h.al) + { + int i; + char oldlabel[13], _far *p, *q; + + for (i = 0, p = dta + 8, q =oldlabel; i < 8; ++i, ++p, ++q) + { + *q = *p; + } + *q++ = '.'; + for (i = 0, p = dta + 16; i < 3; ++i, ++p, ++q) + { + *q = *p; + } + vol_kill(oldlabel); + } + + strcpy(new_label, label); + if (8 < strlen(label)) + { + new_label[8] = '.'; + strcpy(&new_label[9], &label[8]); + } + + /* Parse the filename into an FCB */ + + segread(&sregs); + regs.h.ah = 0x29; + regs.h.al = 0; + regs.x.si = (unsigned)new_label; + regs.x.di = (unsigned)&buf.xfcb_fcb; + sregs.es = sregs.ds; + intdosx(®s, ®s, &sregs); + + /* Volume labels require extended FCB's */ + + buf.xfcb_flag = 0xff; + buf.xfcb_attr = _A_VOLID; + + /* Create the new label */ + + regs.h.ah = 0x16; + regs.x.dx = (unsigned)&buf; + intdos(®s, ®s); + + /* Close the new label */ + + regs.h.ah = 0x10; + regs.x.dx = (unsigned)&buf; + intdos(®s, ®s); + + /* + ** For DOS 5.0 replace the boot record too. + */ + + if(_osmajor > 3) + { + int index, drive = getdrv(); + B_REC boot_record; + + AbsDiskRead(drive, 1, 0, &boot_record); + if(0 == strcmp(boot_record.bsOemName, "MSDOS5.0")) + { + index = 0; + while (NUL != label[index]) + { + boot_record.bsVolumeLabel[index] = label[index]; + index++; + } + for(index; index < 11; index++) + boot_record.bsVolumeLabel[index] = 0x20; + AbsDiskWrite(drive, 1, 0, &boot_record); + } + } + PopDir(); +} + +#ifdef TEST + +void main(int argc, char *argv[]) +{ + if (2 > argc) + { + puts("\aUsage: SETVOL new_name"); + abort(); + } + setvol(argv[1]); +} + +#endif diff --git a/reference/C/CONTRIB/SNIP/sharing.txt b/reference/C/CONTRIB/SNIP/sharing.txt new file mode 100755 index 0000000..f38eeac --- /dev/null +++ b/reference/C/CONTRIB/SNIP/sharing.txt @@ -0,0 +1,70 @@ +From: Mike Ratledge +To: All Msg #245, 03-Aug-88 12:45.00 +Subject: File sharing enabled test + +Someone asked the other day about an easy way to determine if file-sharing +is enabled at program run-time. I use the following code in all of my +Turbo C program to do just that: + +#define TRUE 1 +#define FALSE 0 + +int sharing; + + +main (int argc, char *argv[]) + +{ + sharing = is_sharing(argv[0]); + . + . + . + if (sharing) + { + /* open file in shared mode */ + ... + } + else + { + /* use "normal" open */ + ... + } +} + + +int is_sharing(char *arg) + +{ + FILE *exe; + + if (_osmajor < 3) + return(FALSE); + exe = fopen(arg, "rb"); + ii = lock(fileno(exe), 0l, 500l); + if (ii != -1) + { + ii = unlock(fileno(exe), 0l, 500l); + fclose(exe); + return(TRUE); + } + fclose(exe); + return(FALSE); +} + +What does this code do? First - it checks to make sure it's running under +DOS 3.0+ - if not - no sharing. Next - it opens the program itself (the +.EXE file) by using "argv[0]", which points to the actual program name +complete with the path under DOS 3.0 or later. It then attempts to lock +the first 500 bytes of the program on disk, and if successful (i.e. return +!= -1) it unlocks the same bytes and closes the file (actually - the unlock +is superfluous, since closing the file releases all locks) and returns the +"TRUE" result. If it fails - it closes the .EXE file and returns FALSE. +Note that this does not depend on opening a file in shared mode to test it. + +Note that this code must be modified slightly to be useful for MicroSoft +C, since they use the "locking" procedure for both lock & unlock. You +also have to "rewind" before the unlock, since M/S C works from the +current file-pointer forward. I could post both - but I'm sure all you +C-jockeys out there know what I'm talking about if it concerns you (i.e. +you're using M/S C instead of Turbo). I also have this coded in Turbo +Pascal if anyone needs it... diff --git a/reference/C/CONTRIB/SNIP/shel2dos.c b/reference/C/CONTRIB/SNIP/shel2dos.c new file mode 100755 index 0000000..78c7f9a --- /dev/null +++ b/reference/C/CONTRIB/SNIP/shel2dos.c @@ -0,0 +1,50 @@ +/* +** SHEL2DOS.C - Shell to DOS from a running program +** +** Original Copyright 1989-1991 by Bob Stout as part of +** the MicroFirm Function Library (MFL) +** +** This subset version is hereby donated to the public domain. +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <process.h> + +int shell_to_DOS(void) +{ + char *comspec, prompt[256], *oldprompt; + int retval; + + comspec = getenv("COMSPEC"); + if(comspec == NULL) + comspec = "COMMAND.COM"; /* Better than nothing... */ + + sprintf(prompt, "PROMPT=[Type EXIT to return to program]\r\n%s", + oldprompt = getenv("PROMPT")); + putenv(prompt); + + retval = spawnlp(0, comspec, comspec, NULL); + + sprintf(prompt, "PROMPT=%s", oldprompt); + putenv(prompt); + + return retval; +} + +#ifdef TEST + +#include <stdio.h> + +void main(void) +{ + int retval = shell_to_DOS(); + + printf("shell_to_DOS() returned %d\n", retval); + + retval = shell_to_DOS(); + printf("shell_to_DOS() returned %d\n", retval); +} + +#endif diff --git a/reference/C/CONTRIB/SNIP/snippets._c_ b/reference/C/CONTRIB/SNIP/snippets._c_ new file mode 100755 index 0000000..754ac10 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/snippets._c_ @@ -0,0 +1,42 @@ +Welcome to SNIPPETS! + + All the code I put into SNIPPETS for distribution is Public Domain or free +to the best that I can determine. What this means is that: + +1. I know or can contact the original author(s) to verify the presumed + copyright ownership, and + +2. The work bears an explicit Public Domain notice, or + +3. The work is copyrighted but includes a free use license, or + +4. The work was published without a copyright notice prior to the effective + date of the new copyright law. + + This has been occasionally annoying when I've had to pass up some useful +piece of code because it's questionable whether anyone can use it without +incurring liability (distributing someone else's property makes me an +accessory, doncha know). + + Since SNIPPETS includes both public domain and free code, be sure to +carefully read each header for any free license restrictions which may +apply. + +Distribution: + + Starting with the December 1992 version, SNIPPETS is distributed in two +files: + +SNIPmmyy.LZH is the full SNIPPETS collection. +SNPDmmyy.LZH contains only the files changes since the last release. + + SNIPPETS is distributed through the FidoNet Programmer's Distribution +Network (PDN - see the file PDN.LST for a list of PDN sites and further +information. The SNIPPETS files are also available from my "home" BBS, Comm +Port One, (713) 980-9671, FidoNet address 1:106/2000 using the "magic" F'req +names of "SNIPPETS" and "SNIPDIFF". Various Internet mirror sites also carry +SNIPPETS, but I'm not sure which ones have it an any given time. One place to +try is oak.oakland.edu in /pub/msdos/c. + + ...Bob Stout +------------------------------- Enjoy! ----------------------------------- diff --git a/reference/C/CONTRIB/SNIP/snippets.ndx b/reference/C/CONTRIB/SNIP/snippets.ndx new file mode 100755 index 0000000..7ca4a5a --- /dev/null +++ b/reference/C/CONTRIB/SNIP/snippets.ndx @@ -0,0 +1,468 @@ +|NOTES: "+" preceding file name means new since last SNIPPETS +| "*" preceding file name means modified since last SNIPPETS +| "-" preceding file name means deleted since last SNIPPETS +| +| File Author Description +| ------------ -------------- --------------------------------------------- +* Read.Me Last minute information and instructions ++ File_Id.Diz File info for BBS's +* Snippets.Txt General information about SNIPPETS +* Snippets.(C) SNIPPETS freeware notice +* Snippets.Ndx SNIPPETS index - this file +* Snippets.Wc Count of SNIPPETS files ++ Missing.Txt Rationale of files deleted since last SNIPPETS ++ Nonmsdos.Txt List of universal SNIPPETS functions ++ Dosfuncs.Txt List of MS/PC-DOS-specific SNIPPETS functions +* Pdn.Lst Janis Kracht List of PDN sites + Make.Ini Jim Nutt Master file for NDMAKE + Ansiscrn.H Macros for ANSI.SYS screen control + Cast.H Bob Stout Cast any object to any type +- Dow.H ++ Dd_Struc.H Wayne Hamilton TC/TC++/BC++ DOS file time/date macros + Hilobyte.H Extract high, low bytes from an int ++ Pi.H Useful definitions using PI +* Portable.H Scott Ladd Write portable code for various PC compilers +* Round.H Dave Knapp Rounding macros +* Scrnmacs.H Jerry Houston Macros for direct video work + C_Lines.Awk Dan Kozak AWK program to count lines of C code + 8087_Sav.Asm Jeffrey Nonken Saves/restores 80x87 environment + Coldboot.Asm David Nugent Reliable cold/warm boot + Cpucheck.Asm Determine type of CPU in use + Hires.Asm Switch to 43/50 line mode on EGA/VGA + Ndpcheck.Asm Determine presence of coprocessor ++ Strecpy.Asm L. Satenstein Like strcpy, but returns pointer to NUL + A2E.C Bob Stout ASCII <=> EBCDIC conversions + Addhndls.C Doug Burger Allow more than 20 open files under DOS 3+ + Bob Jarvis ++ Addpath.C Bob Stout Add directories to path in AUTOEXEC.BAT + Amalloc.C Paul Schlyter Multi-dimensional array allocate ( <64K on PC) +* Ansiflen.C Bob Jarvis ANSI-compliant file size function + Ansiload.C Bob Jarvis Detect ANSI.SYS + Ansiself.C Thad Smith Self-replicating program in ANSI C + Ansisys.C Detect ANSI.SYS + Approx.C John Rex Fuzzy string search + Assignpr.C Bob Stout Multiple printer support + Atr2Ansi.C Bob Stout Build ANSI.SYS command string, given attribute + Bascnvrt.C Bob Stout Convert radix of a numeric string + Bastrngs.C Bob Stout BASIC-like string functions + Bitarray.C Bit array functions + Bitcnt_1.C Ratko Tomic Count bits in a number (fast, clever) + Bitcnt_2.C Count bits in a number (fascinating) + Bitfiles.C Aare Tali Bit I/O for buffered (fopen'ed) files + Bitops.C Bob Stout Small bit array macros + Bitstrng.C J. Blauth Format numeric value as string of bits ++ Bstr_I.C Bob Stout Convert binary string to int ++ Break.C Bob Stout Control DOS "SET BREAK=" status ++ Bresnham.C Brian Dessent Draw lines and circles + Calsupp.C Ray McVay Calendar support funtions + Cant.C Bob Stout An fopen() replacement with error trapping + Changprn.C Bob Stout Change the standard printer device + Checkexe.C Bob Jarvis Checksum protection for executable files ++ Checksum.C Bob Stout Calculate checksum + Chgext.C Bob Stout Change/add a file name extension + Clock.C Jon Guthrie On-screen clock generator + Combin.C Thad Smith III Compute combinations without overflow + Commafmt.C Bob Stout Add thousands separators to numeric strings ++ Compiler.C Test for popular PC compilers & versions +* Crc-16.C Calculated 16-bit CRC + Crc-16F.C Fast 16-bit CRC + Crc_32.C Gary S. Brown Table lookup 32-bit CRC +* Crypt.C Bob Stout S-Coder data encryption from DDJ + Ctrlprnt.C Bob Stout Print a line, displaying Ctrl characters + Cubic.C Ross Cottrell Solve cubic equations + Cursor.C Bill Wilkie Cursor management/manipulation + Dbl2Long.C Ross Cottrell Rounds doubles to longs + Dblround.C Ross Cottrell Rounds a double to nearest whole number +- Dd_Struc.C + Doscopy.C Peter Yard Copy a file ++ Droptime.C Thor Johnson Give up time slices to Win, OS/2, etc. +* Drvalid.C Bob Stout Benignly validate disk drives ++ Drvs.C David Gersic Checks for valid disk drives, local or remote +* Dspdtst.C I/O benchmark - MSC/TC/ZTC/Watcom +* Editgets.C Jon Burchmore Get an input string with editing functions + Bob Stout ++ Eng.C David Harmon Floating point value -> engineering notation + Errfix.C Bob Jarvis Redirect stderr to a file + Eval.C Bob Stout Simple arithmetic expression evaluator + Factoryl.C Bob Stout Factorial, combinations, permutations +* Faskbhit.C D. Goodenough Fast kbhit() and kbflush() + Favail.C Bob Stout How many more files may be fopen'ed? + Fcompare.C Bob Stout Compare 2 files for equality + Fcopy.C Bob Jarvis Copy a file + Ferrorf.C Mark Devlin Formatted error messages +- Figets.C + Files.C Matthew Hunt Determine number of FILE set in CONFIG.SYS + Fmtmoney.C Bob Stout Format US dollar amounts into text strings + Fndislot.C Bob Stout Locate an unused user interrupt vector + Format.C Bob Stout Use DOS format to format a diskette ++ Fpswitch.C Demo how to use function pointer arrays + Fscanbin.C Ray Gardner Scan binary fields via format string ++ Fsize.C Bob Stout Return true apparent size of buffered file + Fsm.C Demonstrates a finite state machine + Getdcwd.C Bob Jarvis Get current working directory for given drive + Getkey.C Bob Stout Get extended key codes + Getseg.C Bob Stout Get segment and offset of any object + Getstrng.C Ron Sires Safe gets() for input string of unknown length + Glbl_Env.C Peter Thomas Update & remove global environment variables + Grafline.C David Harmon Demo of PC line drawing characters ++ Hexorint.C Bob Stout Auto-convert hex or decimal strings + Howdy.C Obfuscated C code +* Hstr_I.C Bob Stout Convert hex string to int +* Hugeread.C Bob Stout Read & write huge data using far pointers + Hugesort.C Ray Gardner Quicksort using huge pointers + Initvars.C Ray Gardner Read data into variables + Iscons.C Bob Stout Does a FILE * refer to the console? + Isfopen.C Bob Stout Is a FILE * in use? ++ Isisbn.C Maynard Hogg Validate ISBN (book) numbers + Isnetdr.C Bob Dolan Determine is a drive is local or remote + Ispow2.C Is a number an integral power of 2? + Isqrt.C Integer square root + Isramdsk.C Bob Stout Determine if a drive is a RAM disk ++ Isshare.C Mike Ratledge Determine if file sharing is enabled + Isshift.C Jeff Dunlop Determine if a shift key is pressed +* Iswprot.C Bob Stout Determine is a floppy is write protected + Wayne King ++ Isxkbrd.C Ed Kowalski Detects extended (101+ key) keyboard + Jdn.C Paul Schlyter Julian Day Number computation + Ray Gardner + Joystick.C Bob Stout Joystick support functions +* Kb_Data.C Dan Kozak Keyboard status determination +* Keylocks.C Caps/Num lock set/clear functions + Keywatch.C Robert Mashlan Demonstrates capturing keyboard interrupt + Lbitops.C Scott Dudley Large bit array macros + Ldfloor.C Ray Gardner Long double floor +* Ll_Msort.C Ray Gardner Linked list mergesort + Ll_Qsort.C Jon Guthrie Linked list quicksort +* Lsary.C Bob Stout Read a directory into a linked list + Ltoa.C Bob Stout Convert long to a string + Ltostr.C Thad Smith III Convert long to a string + Lv1Ws.C Bob Stout Convert whitespace strings to single spaces + Mainmain.C Obfuscated C code + Mcb_Env.C Modify master environment using MCB's + Mdalloc.C Blair Haukedal Multi-dimentional array alloction + Memavail.C Thor Johnson Report available DOS memory + Memrev.C Ray Gardner Assymetrical memory swap + Mkdirs.C Bob Stout Build directory tree (deep mkdir()) +* Moon_Age.C M. Jones Determine the phase of the moons for any date ++ Msb2Ieee.C Jeffrey Foy Convert MSBIN format to/from IEEE float + Noctrlc.C Traps Ctrl-C, Ctrl-Break, Ctrl-Alt-Del + Noreset.C Traps Ctrl-Alt-Del +* Ord_Text.C Bob Stout Format ordinal numbers in English ++ Os_Id.H David Gibbs Header for determining PC OS's ++ Os_Id.C David Gibbs Determine PC OS +* Pcnvrt.C Bob Stout Convert Pascal strings to C + Perm_Idx.C Thad Smith III Determine permutation index + Pfopen.C David Engel Open a file anywhere + Pluraltx.C Bob Stout How to print proper plurals + Prtoggle.C Bob Stout Tee stdio to stdprn + Prtscrn.C Bob Stout Invoke BIOS print screen function + Prtstat.C Bob Stout Determine printer status +* Pushdir.C Bob Stout Stack-oriented CHDIR functions + Rand1.C Phil Linttell Random number generator + Rand2.C E. Schneider Random number generator + Reboot.C Bob Stout Simple PC reboot function in C + Redir.C F. Piette Demonstrates output redirection +* Rg_Isort.C Ray Gardner Insertion sort function + Rg_Qsort.C1 Ray Gardner Non-Recursive ANSI quicksort function +* Rg_Qsort.C2 Ray Gardner Recursive ANSI quicksort function +* Rg_Rand.C Ray Gardner Minimal random number generator + Rg_Ssort.C Ray Gardner ANSI quicksort-compatible shellsort function + Rmallws.C Bob Stout Remove all whitespace from a string + Rmlead.C Bob Stout Remove leading whitespace from a string + Rmtrail.C Bob Stout Remove trailing whitespace from a string + Rndmize.C How to seed ANSI random number generator + Scanfrac.C Thad Smith III Scans/converts text fractions +* Scroll.C Bob Stout Scroll screen function + Setenvar.C Bob Stout Set DOS master environment *legally* +* Shel2Dos.C Bob Stout Shell to DOS from a running program + Soundex.C Bob Jarvis Standard English soundex + Speed.C Benchmark to calculate I/O performance ++ Spin.C Demo of how to make various text "spinners" +* Srchfile.C Bob Stout Search files for text, forwards & backwards + Sstrcpy.C Ray Gardner Overlapping strcpy() & strcat() work-alikes + Stats.C Bob Stout Analyze file statistics + Stptok.C Ray Gardner Improved tokenizing function ++ Str27Seg.C Bob Stout Convert numeric string to 7-segment displays + Strftime.C Jim Nutt Non-locale version of ANSI strftime() + Rob Duff + Strrepl.C Gilles Kohl Replace substrings + Strrev.C Bob Stout Reverse a string in place using XOR swapping + Strsort.C Ray Gardner (Shell) Sort a string array + Strucfil.C Lynn Nash Read/write structures to/from a file + Style.C Suggested coding style guidelines ++ Tabtrick.C Demo using printf() for columnar formatting + Timegetc.C Bob Jarvis Wait specified time for a keypress + Toascii.C EBCDIC-ASCII conversion arrays + Tp6Tod.C Thad Smith III Convert TP 6-byte reals to C doubles ++ Translat.C Jerry Coffin Translate string w/ C-style escape sequences + Trim.C Bob Stout Trim leading, trailing, & embedded spaces + Truename.C gk Normalize filename using undocumented DOS + Unix2Dos.C Bob Stout Convert Unix-style pathnames to DOS-style ++ Vfname.C Sid Rogers Validate DOS-legal file names + Video.C Jeff Dunlop C video information functions +* Wb_Fcopy.C Walter Bright Fast file copy/append + Weird.C Obfuscated C code +* Whicharc.C Heinz Ozwirk Determine which archiver used on a packed file + David Gersic +* Windchil.C Compute wind chill factor + Wordwrap.C Robert Morgan Simple CRT word wrap demonstration + Xstrcat.C String concatenation funct + Xstrcmp.C S. Offermann Compare strings using DOS wildcards +| +|-------------- FAQ file (answers to Frequently Asked Questions -------------- +| +* C_Prec.Txt Operator precedence/associativity in C / C++ + Storage.Typ Jeff Galbraith C storage types crib sheet + Rtlftrul.Txt Right-left rule for reading C +* Ptr_Help.Txt Ted Jensen Helpful hints on pointers + C_Port.Txt Joseph Carnage How to write portable C code + Enums.Txt Helpful hints for enums +* Which_C.Txt Bob Stout Guidelines for choosing a PC C compiler +* Resource.Lst J-Mag Guthrie C/C++ resources (books, magazines, vendors) + Environ.Txt Bob Stout Notes on changing the master environment + Sharing.Txt Mike Ratledge How to check if file sharing is active + Evsavres.Txt How to blank/restore EGA/VGA screen + Ansisys.Txt Chart of ANSI screen control codes ++ Vt100.Txt Jon Guthrie Chart of VT-100 escape codes +| +|-------------- Jim Nutt's direct video functions ---------------------------- +| + Vio.H Direct screen package + Vio.Asm " " " + Scrnsave.C Bob Stout Save and restore text screens +| +|-------------- Bob Stout's Int 2Eh functions -------------------------------- +| + Int2E.Asm Access command processor "back door" + Ccomcall.C C "glue" to use Int 2Eh +| +|-------------- Bob Stout's POSIX compliant directory functions -------------- +| +* Dirent.H POSIX compliant header +* Rfind1St.C Compiler-independent find first/next functions + Posixdir.C opendir(), readdir(), seekdir(), closedir() + Posix_Ls.C Directory lister demo +| +|-------------- J. Kercheval's PD regular expression comparator -------------- +| + Match.H Header file + Match.C Portable source including optional test code + Match.Doc Documentation for Match.C +| +|-------------- Bob Stout/Sreenath Chary file name processing functions ------ +| + Dirmask.C Bob Stout Complex pattern matching (calls patmat()) + Patmat.C Sreenath Chary String pattern matching + Fln_Fix.C Bob Stout Crunch dot directories, verify DOS-valid paths + Flnorm.C Bob Stout Full file name normalization +| +|-------------- Bob Stout/Lynn Lively/David Fox sound & timing package ------- +| + Uclock.H David L. Fox Microsecond timing function header +* Uclock.C " " " Microsecond resolution timing functions + Sound.H Bob Stout Sound functions header + Sound.C " " Speaker control functions + Mktone.C " " Tone generation functions + Playlib.C Lynn R. Lively Background music package + Playdemo.C Bob Stout Demo of backgroud music package +| +|-------------- Greg Messer's C/C++ comment extractor ------------------------ +| + Getcmt.C Greg Messer Extract comments from C/C++ source files + Testcmt.C " " Test file for above +| +|-------------- Ray Gardner's scalar date function with calendar demo -------- +| ++ Scaldate.H Ray Gardner Scalar ("Julian") date header +* Scaldate.C Ray Gardner Scalar ("Julian") date functions +* Daynum.C Bob Stout Return statistics about a given date + Cal.C Bob Stout Calendar using Scaldate.C +| +|-------------- Ruurd Pels's FOSSIL access functions ------------------------- +| +* X00Api.H C header w/ prototype declarations +* X00Api.C C access functions +| +|-------------- Robert Mashlan's PRINT.COM interface functions --------------- +| +* Prnspool.H C header w/ prototype declarations + Prnspool.C PRINT.COM spool queue functions + Printq.C Demo program for above +| +|-------------- Robert Mashlan's memory allocation strategy functions -------- +| + Strat.H C header w/ prototypes and enum'ed constants + Strat.C C functions +| +|-------------- Jerry Coffin's word wrapping functions ----------------------- +| + W_Wrap.H C header w/ prototypes and enum'ed constants + W_Wrap.C C functions + Center.C Center a wrapped line +| +|-------------- Bob Stout's absolute sector read/write functions ------------- +| + Dos5Boot.H Header for boot sector access +* Absdiskc.C C read and write functions + Absdisk.Asm Low-level code for disk I/O, DOS 2-5 +| +|-------------- Mouse functions ---------------------------------------------- +| + Mouse.H Bob Jarvis Header w/ prototypes +* Mouse.C Bob Jarvis Essential mouse stuff + Scrnpick.C Ray McVay Demo, retrieves text from screen using mouse +| +|-------------- Martin Maney's fast line buffered file input ----------------- +| + Xfile.H Header w/ prototypes + Xfile.C Contains xopen(), xclose(), xgetline() + Xtest.C Demo for above +| +|-------------- Functions to get command line options ------------------------ +| + Getopt3.C AT&T compatible getopt(3) ++ Getopts.H Bob Stout Header for Getopts.C +* Getopts.C Bob Stout Scan command line for switches +| +|-------------- String searching functions ----------------------------------- +| +* Pbmsrch.C Jerry Coffin Pratt-Boyer-Moore string search +* Bmhsrch.C Ray Gardner Case-sensitive Boyer-Moore-Horspool search +* Bmhisrch.C Thad Smith Case-insensitive Boyer-Moore-Horspool search +* Bmhasrch.C Ray Gardner Case-insensitive BMH search w/ accented chars +| +|-------------- Bob Stout's extended keyboard stuff -------------------------- +| + Ext_Keys.H Header to define extended key codes + Ext_Keys.C A getch() work-alike for extended keyboards +| +|-------------- Mark Kimes ANSI screen code interpreter ---------------------- +| + Doansi.H Header file + Doansi_1.C Portable intepreter + Doansi_2.C OS-specific support functions +| +|-------------- David Gibbs' multitasker functions for Win, OS/2, & DV ------- +| ++ Tasker.Txt Description of Tasker functions ++ Tasker.H Header, structs, and prototypes ++ Tasker.C Detect multitasker and give up time slices +| +|-------------- PC compiler compatibility functions -------------------------- +| + Biport.H Bob Stout Header to port Borland _geninterrupt() + Biport.C Bob Stout Port Borland code using pseudovariables +* Fmemops.C Bob Stout Emulate MSC's _fmemxxx() in BC++ & ZTC++ + Ftime.H Jeff Dunlop BC++-style file date/time struct & prototypes + Ftime.C Jeff Dunlop BC++-style file date/time functions +* Msc_Peek.C Bob Stout Add peek/poke to MSC + Pmerge.C Bob Stout Portable fnmerge(), _makepath() equivalents +* Psplit.C Bob Stout Portable fnsplit(), _splitpath() equivalents ++ Strdup.C Bob Stout Portable strdup() ++ Strupr.C Bob Stout Portable strupr() strlwr() +* Vidport.C Bob Stout Portable gotoxy(), clrscr() equivalents, etc. ++ Big_Mall.H Bob Stout Portably allocate memory > 64Kb +| +|-------------- Bob Stout's Portable PC exception handling ------------------- +| + Except.Doc Information on programs below + Cctrap.Asm Int 23h (Ctrl-C) trap + Cbtrap.Asm Int 1Bh (Ctrl-Break) trap + Trapflag.Asm Trap & flag Ints 23h & 1Bh + Trapdemo.C Demo of TRAPFLAG.ASM + Cerrinst.Asm Install DOS critical error handler + Cerrtrap.Asm DOS critical error handler +| +|-------------- David Nugent's iostreams (C++) tutorial ---------------------- +| ++ Iostutor.Txt Tutorial for following demo code ++ Myio.H Header for Myio.Cpp ++ Myio.Cpp Simple I/O class ++ Mystream.H iostream Interface for class Myio ++ Mystream.Cpp ios Interface implementation ++ Myline.H Simple line input classes ++ Myline.Cpp Implementation of myLine classes ++ Myiodemo.Cpp myio Loopback demo ++ Myio.Mak Makefile for Iostutor.Txt demo files +| +|-------------- David Nugent's simple string class --------------------------- +| ++ Str.Doc Information on the string class ++ Str.H C++ header ++ Str.Cpp Simple, portable C++ string class +| +|-------------- Walter Bright's memory allocation debugging package ---------- +| ++ Mem.Txt Information on the Mem package ++ Toolkit.H Compiler-independent portability header ++ Mem.H Mem package header ++ Mem.C Mem package code +| +|-------------- DOS utilities as demos --------------------------------------- +| + 2Dlife.C Jon Guthrie 2-D Life program + Bigfac.C Carl Declerck Do large factorials using ASCII multiply + Bincomp.C Ray Gardner Binary file comparison utility + Bordcolr.C Bob Jarvis Set border color + C_Cmnt.C Thad Smith Extract comments from a C source file + Cdir.C Lynn R. Lively Like DOS CHDIR except changes drives as well + Chbytes.C Bob Stout Edit binary files in place +* Chmod.C Bob Stout Change DOS file attributes - wildcards, etc. ++ Cmdline.C Demonstation how to access command line args + Commconv.C Jari Laaksonen Convert C++ style comments to C style + Cursize.C Bob Jarvis Set the cursor size + Do.C Specify multiple command line commands + Dossort.C Robert Mashlan DOS SORT work-alike +* Drivsrch.C Marty Connely Search for physical/logical drives + Dspclock.C Mike Jones On-screen TSR clock + Factor.C Ray Gardner Print prime factorization of a number (double) + Filcount.C Bob Stout Count files/directories ++ Flopcopy.C Bob Stout Copy a floppy to a HD subdirectory +* Fraction.C Thad Smith Convert a real number to an integer ratio + Getvol.C Bob Stout Retrieve a disk volume label + Head.C Unix head work-alike + Hexdump.C Paul Edwards Hex/ASCII file dump utility + Ifactor.C Ray Gardner Print prime factorization of a number (long) ++ Inchcvrt.C Bob Stout Convert inches to feet/inches and fractions + Kbflip.C Bob Stout Set/clear Caps/Num/Scroll locks + Killff.C Jerry Gore Strip FF characters from text files + Erik VanRiper + Log.C Robert Sprawls Utility to log working time +* Lsd.C Bob Stout DOS DIR enhanced work-alike + Lzhuf.C Yoshi Compression used in LHARC & LHA + Maze_1.C Jon Guthrie Maze generator + Maze_2.C Obfuscated maze generator ++ Maze_3.C Cute maze generator. Run, then enter size. + Morse.C Mike Dodd Convert strings to morse code + Mterm.C David Harmon Micro terminal (comm) program - use with X00 +* Mv.C Ray McVay Move files + Palndrom.C Dan Hoey Self-replicating palindrome - try it! + Permute1.C Dave Chapman Permute strings + Permute2.C Jon Guthrie Permute strings + Pi.C Calculate PI to 60,000 digits or more ++ Pr.C Print a file with headers & breaks + Query.C Bob Stout Timed query w/default for batch files + Rdxcnvrt.C Bob Stout Convert between number bases +* Remtab.C Robert Mashlan Convert tabs to spaces +* Rm_All.C Bob Stout Remove all files - now supports recursion + Roman.C Jim Walsh Convert Arabic number to Roman numeral + Setimeto.C Bob Stout Set a file's time/datestamp to match another's +* Setvol.C Bob Stout Set, change, or kill a disk volume label ++ Split.C Bob Stout Split large text files into smaller ones + Stripeof.C Bob Stout Strip ^Z characters from DOS text files +* Stub.C Bob Stout Truncate .OBJ (and other) files + Sunriset.C Paul Schlyter Computes length of day at any place on Earth +* Tail.C Joe Huffman Print last n (default = 5) lines of a file + Ruurd Pels ++ Todaybak.C Bob Stout Back up today's files to a floppy + Touch.C Ray L. McVay TC/TC++/BC++ set file time/date stamp + Treedir.C Bob Stout Recursive directory lister + Uuencode.C Don Kneller Unix uuencode + Uudecode.C John Lots Unix uudecode + Wc.C Jay Elkes Like Unix wc, counts lines, words, chars + Where.C Search for a file +| +|-------------- Various flavors of grep utilities ---------------------------- +| ++ Jgrep.C Jerry Coffin Simple and portable ++ Grep.C DECUS "Real" grep - free with some strings diff --git a/reference/C/CONTRIB/SNIP/snippets.txt b/reference/C/CONTRIB/SNIP/snippets.txt new file mode 100755 index 0000000..1640804 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/snippets.txt @@ -0,0 +1,23 @@ +INFORMATION ABOUT SNIPPETS APR 94 EDITION +========================================= + +Beginning with the Dec '92 edition, SNIPPETS is being distributed in two +forms. + +The first, and most familiar, is the full SNIPPETS collection. As before it +is named "SNIPdddd.xxx", where "dddd" is the release date and "xxx" is the +archive utility extension. For example, I distribute the Apr '94 edition as +SNIP9404.LZH, using the LHA.EXE archive utility. + +New to the Dec '92 release was SNIPDIFF, an archive containing both files and +a utility to create a complete and fully-validated SNIPPETS archive using +files from the last edition of SNIPPETS which haven't changed. This +represents a considerable saving in the size of the archive and, +consequently, the time required to download it from bulletin boards and +public information services. + +Beginning the Apr '93 release, SNIPDIFF became even smaller with the +inclusion of DSAPP.EXE which allows that only the differences for changed +files need be included. DSAPP.EXE is a public domain utility for applying +changes, written by David Burton, and which is distributed with his excellent +TLIB revision control system. diff --git a/reference/C/CONTRIB/SNIP/snippets.wc b/reference/C/CONTRIB/SNIP/snippets.wc new file mode 100755 index 0000000..b7d32e2 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/snippets.wc @@ -0,0 +1,373 @@ + WC 3.00á  + +File Lines Words Chars +--------------------------------- ------- ------- ------- +READ.ME 1 10 70 +FILE_ID.DIZ 6 38 208 +SNIPPETS.TXT 23 179 1155 +SNIPPETS.(C) 42 269 1743 +SNIPPETS.NDX 468 3355 26369 +SNIPPETS.WC 0 0 0 +MISSING.TXT 21 172 1036 +NONMSDOS.TXT 42 426 2773 +DOSFUNCS.TXT 34 338 2251 +PDN.LST 184 1429 10435 +MAKE.INI 190 465 3851 +ANSISCRN.H 72 317 2304 +CAST.H 23 50 1240 +DD_STRUC.H 31 187 1019 +HILOBYTE.H 2 13 82 +PI.H 6 20 115 +PORTABLE.H 166 636 5187 +ROUND.H 11 37 215 +SCRNMACS.H 92 334 2405 +C_LINES.AWK 43 184 1269 +8087_SAV.ASM 73 389 2797 +COLDBOOT.ASM 42 141 1042 +CPUCHECK.ASM 78 280 2689 +HIRES.ASM 37 154 1214 +NDPCHECK.ASM 44 128 1152 +STRECPY.ASM 92 418 3375 +A2E.C 51 544 2598 +ADDHNDLS.C 104 349 3076 +ADDPATH.C 101 278 2550 +AMALLOC.C 124 445 3469 +ANSIFLEN.C 34 75 594 +ANSILOAD.C 66 194 1278 +ANSISELF.C 10 75 403 +ANSISYS.C 60 136 1822 +APPROX.C 168 540 4931 +ASSIGNPR.C 56 216 1583 +ATR2ANSI.C 80 252 1894 +BASCNVRT.C 49 141 1027 +BASTRNGS.C 144 350 2907 +BITARRAY.C 15 49 417 +BITCNT_1.C 41 96 686 +BITCNT_2.C 33 85 695 +BITFILES.C 138 335 2943 +BITOPS.C 13 45 320 +BITSTRNG.C 59 243 1683 +BREAK.C 29 65 465 +BRESNHAM.C 155 521 3573 +BSTR_I.C 40 84 654 +CALSUPP.C 65 207 1375 +CANT.C 22 59 447 +CHANGPRN.C 52 130 1103 +CHECKEXE.C 126 344 3219 +CHECKSUM.C 39 111 789 +CHGEXT.C 71 217 1687 +CLOCK.C 200 540 5401 +COMBIN.C 66 263 1603 +COMMAFMT.C 82 216 2018 +COMPILER.C 46 182 1370 +CRC-16.C 37 125 988 +CRC-16F.C 130 535 4603 +CRC_32.C 172 952 8578 +CRYPT.C 98 355 3673 +CTRLPRNT.C 40 95 767 +CUBIC.C 61 246 1453 +CURSOR.C 52 190 2348 +DBL2LONG.C 64 326 1984 +DBLROUND.C 35 82 618 +DOSCOPY.C 58 183 1856 +DROPTIME.C 21 70 535 +DRVALID.C 166 440 3556 +DRVS.C 43 199 1391 +DSPDTST.C 149 525 4122 +EDITGETS.C 371 919 12377 +ENG.C 50 124 1058 +ERRFIX.C 52 180 1490 +EVAL.C 314 665 6992 +FACTORYL.C 103 329 2532 +FASKBHIT.C 28 69 519 +FAVAIL.C 54 116 967 +FCOMPARE.C 59 146 1314 +FCOPY.C 55 129 1192 +FERRORF.C 25 94 662 +FILES.C 93 346 2336 +FMTMONEY.C 119 277 2461 +FNDISLOT.C 48 131 1023 +FORMAT.C 56 156 1210 +FPSWITCH.C 81 140 1358 +FSCANBIN.C 115 378 3497 +FSIZE.C 78 223 1872 +FSM.C 37 79 786 +GETDCWD.C 74 213 1622 +GETKEY.C 27 55 459 +GETSEG.C 49 149 1127 +GETSTRNG.C 66 176 1612 +GLBL_ENV.C 364 1328 10051 +GRAFLINE.C 29 201 1346 +HEXORINT.C 54 132 967 +HOWDY.C 21 129 516 +HSTR_I.C 48 113 877 +HUGEREAD.C 242 653 5628 +HUGESORT.C 105 331 2745 +INITVARS.C 139 568 5089 +ISCONS.C 39 108 801 +ISFOPEN.C 41 102 774 +ISISBN.C 25 59 480 +ISNETDR.C 45 131 1184 +ISPOW2.C 12 35 221 +ISQRT.C 91 349 2390 +ISRAMDSK.C 56 187 1339 +ISSHARE.C 86 300 2179 +ISSHIFT.C 24 75 878 +ISWPROT.C 82 244 1773 +ISXKBRD.C 47 126 1101 +JDN.C 124 711 4955 +JOYSTICK.C 74 192 1523 +KB_DATA.C 50 262 2159 +KEYLOCKS.C 21 29 282 +KEYWATCH.C 155 608 5174 +LBITOPS.C 46 170 1184 +LDFLOOR.C 41 172 1597 +LL_MSORT.C 77 253 1862 +LL_QSORT.C 146 450 3839 +LSARY.C 112 322 2536 +LTOA.C 58 174 1444 +LTOSTR.C 57 181 1463 +LV1WS.C 36 82 827 +MAINMAIN.C 1 19 79 +MCB_ENV.C 166 520 4380 +MDALLOC.C 160 676 5322 +MEMAVAIL.C 32 64 479 +MEMREV.C 52 199 1419 +MKDIRS.C 52 125 1071 +MOON_AGE.C 66 263 2055 +MSB2IEEE.C 59 214 1713 +NOCTRLC.C 63 147 1618 +NORESET.C 103 314 2813 +ORD_TEXT.C 33 85 632 +OS_ID.H 41 114 732 +OS_ID.C 134 404 2804 +PCNVRT.C 22 79 623 +PERM_IDX.C 37 141 995 +PFOPEN.C 78 228 1650 +PLURALTX.C 19 62 385 +PRTOGGLE.C 91 289 2389 +PRTSCRN.C 53 113 932 +PRTSTAT.C 68 156 1189 +PUSHDIR.C 192 598 4993 +RAND1.C 239 1017 7510 +RAND2.C 51 143 1254 +REBOOT.C 32 64 476 +REDIR.C 59 221 1672 +RG_ISORT.C 18 62 402 +RG_QSORT.C1 150 696 6666 +RG_QSORT.C2 50 107 1021 +RG_RAND.C 88 254 1949 +RG_SSORT.C 43 105 1148 +RMALLWS.C 28 67 538 +RMLEAD.C 26 65 506 +RMTRAIL.C 31 67 577 +RNDMIZE.C 1 6 40 +SCANFRAC.C 119 471 3913 +SCROLL.C 47 180 1752 +SETENVAR.C 155 448 3950 +SHEL2DOS.C 50 136 1052 +SOUNDEX.C 43 85 1066 +SPEED.C 155 533 3773 +SPIN.C 29 93 838 +SRCHFILE.C 225 679 5792 +SSTRCPY.C 13 30 207 +STATS.C 53 162 1731 +STPTOK.C 38 142 1074 +STR27SEG.C 148 378 3814 +STRFTIME.C 339 1021 9652 +STRREPL.C 74 251 1946 +STRREV.C 37 74 607 +STRSORT.C 34 91 876 +STRUCFIL.C 190 614 5210 +STYLE.C 32 106 1701 +TABTRICK.C 54 154 1607 +TIMEGETC.C 44 108 778 +TOASCII.C 37 518 2393 +TP6TOD.C 74 255 1844 +TRANSLAT.C 71 164 1625 +TRIM.C 78 138 1610 +TRUENAME.C 103 268 2022 +UNIX2DOS.C 15 33 252 +VFNAME.C 226 732 6346 +VIDEO.C 181 541 5858 +WB_FCOPY.C 86 300 2510 +WEIRD.C 13 43 264 +WHICHARC.C 251 912 8388 +WINDCHIL.C 19 68 504 +WORDWRAP.C 92 217 2242 +XSTRCAT.C 32 79 664 +XSTRCMP.C 67 132 1525 +C_PREC.TXT 74 215 4040 +STORAGE.TYP 78 379 1915 +RTLFTRUL.TXT 140 696 4896 +PTR_HELP.TXT 1117 7108 41674 +C_PORT.TXT 340 1771 12290 +ENUMS.TXT 55 281 2077 +WHICH_C.TXT 283 2317 14183 +RESOURCE.LST 459 2221 16375 +ENVIRON.TXT 63 624 3854 +SHARING.TXT 70 335 1968 +EVSAVRES.TXT 5 34 236 +ANSISYS.TXT 226 1151 10351 +VT100.TXT 199 1037 9300 +VIO.H 90 283 1787 +VIO.ASM 896 1875 9514 +SCRNSAVE.C 79 198 1627 +INT2E.ASM 55 169 1464 +CCOMCALL.C 36 87 636 +DIRENT.H 97 292 2489 +RFIND1ST.C 156 493 5501 +POSIXDIR.C 276 824 10098 +POSIX_LS.C 83 405 2934 +MATCH.H 107 523 3963 +MATCH.C 585 1675 18755 +MATCH.DOC 126 827 5288 +DIRMASK.C 73 252 2956 +PATMAT.C 75 428 4693 +FLN_FIX.C 142 354 3939 +FLNORM.C 158 504 4735 +UCLOCK.H 53 153 1134 +UCLOCK.C 106 451 3683 +SOUND.H 181 528 3836 +SOUND.C 30 71 568 +MKTONE.C 52 136 1118 +PLAYLIB.C 137 334 2672 +PLAYDEMO.C 37 105 747 +GETCMT.C 267 968 9461 +TESTCMT.C 16 53 316 +SCALDATE.H 27 135 773 +SCALDATE.C 49 190 1327 +DAYNUM.C 104 339 2365 +CAL.C 144 461 3496 +X00API.H 236 886 7444 +X00API.C 411 1308 10833 +PRNSPOOL.H 48 167 1281 +PRNSPOOL.C 151 389 3117 +PRINTQ.C 46 156 1411 +STRAT.H 22 68 432 +STRAT.C 170 497 3889 +W_WRAP.H 5 27 143 +W_WRAP.C 139 735 5059 +CENTER.C 49 181 1285 +DOS5BOOT.H 40 162 2185 +ABSDISKC.C 34 115 1023 +ABSDISK.ASM 72 269 2126 +MOUSE.H 38 175 1119 +MOUSE.C 352 1183 9063 +SCRNPICK.C 58 222 1608 +XFILE.H 41 96 707 +XFILE.C 200 706 5019 +XTEST.C 35 79 786 +GETOPT3.C 102 404 3077 +GETOPTS.H 31 67 605 +GETOPTS.C 193 551 6021 +PBMSRCH.C 95 299 2511 +BMHSRCH.C 68 231 2084 +BMHISRCH.C 94 365 3051 +BMHASRCH.C 104 609 3632 +EXT_KEYS.H 98 388 3089 +EXT_KEYS.C 56 153 1326 +DOANSI.H 33 176 972 +DOANSI_1.C 478 1009 13041 +DOANSI_2.C 229 675 4435 +TASKER.TXT 78 470 3028 +TASKER.H 44 104 714 +TASKER.C 127 360 2576 +BIPORT.H 34 154 811 +BIPORT.C 16 47 315 +FMEMOPS.C 52 163 1200 +FTIME.H 20 60 499 +FTIME.C 58 129 1157 +MSC_PEEK.C 48 118 881 +PMERGE.C 69 178 1504 +PSPLIT.C 110 286 2602 +STRDUP.C 15 32 258 +STRUPR.C 29 42 436 +VIDPORT.C 114 288 2348 +BIG_MALL.H 15 54 400 +EXCEPT.DOC 184 1333 8755 +CCTRAP.ASM 64 190 1586 +CBTRAP.ASM 63 166 1384 +TRAPFLAG.ASM 133 428 3753 +TRAPDEMO.C 74 146 1460 +CERRINST.ASM 100 345 2990 +CERRTRAP.ASM 134 551 4628 +IOSTUTOR.TXT 260 2112 12414 +MYIO.H 98 317 2624 +MYIO.CPP 127 402 3544 +MYSTREAM.H 92 190 1712 +MYSTREAM.CPP 142 430 3650 +MYLINE.H 43 158 1336 +MYLINE.CPP 76 218 1762 +MYIODEMO.CPP 168 464 3955 +MYIO.MAK 107 315 2073 +STR.DOC 47 286 1940 +STR.H 322 821 6681 +STR.CPP 303 760 6188 +MEM.TXT 215 1401 8956 +TOOLKIT.H 66 226 1604 +MEM.H 212 868 6115 +MEM.C 681 1910 13156 +2DLIFE.C 111 315 2636 +BIGFAC.C 122 350 2875 +BINCOMP.C 172 479 4077 +BORDCOLR.C 109 355 2751 +C_CMNT.C 154 502 4984 +CDIR.C 127 372 3326 +CHBYTES.C 203 680 6476 +CHMOD.C 224 686 5828 +CMDLINE.C 28 85 638 +COMMCONV.C 97 300 2459 +CURSIZE.C 66 193 1486 +DO.C 17 39 324 +DOSSORT.C 118 330 3073 +DRIVSRCH.C 84 302 2238 +DSPCLOCK.C 83 284 2473 +FACTOR.C 80 209 1688 +FILCOUNT.C 93 286 2334 +FLOPCOPY.C 120 391 3150 +FRACTION.C 91 321 2743 +GETVOL.C 68 210 1486 +HEAD.C 40 132 1006 +HEXDUMP.C 88 243 2052 +IFACTOR.C 66 147 1253 +INCHCVRT.C 79 207 1844 +KBFLIP.C 86 295 2301 +KILLFF.C 123 475 4032 +LOG.C 216 750 7625 +LSD.C 265 786 6964 +LZHUF.C 646 2501 18271 +MAZE_1.C 183 483 4201 +MAZE_2.C 1 74 238 +MAZE_3.C 7 67 441 +MORSE.C 238 1002 7306 +MTERM.C 133 419 3871 +MV.C 136 377 3096 +PALNDROM.C 2 74 277 +PERMUTE1.C 114 374 3436 +PERMUTE2.C 79 187 1721 +PI.C 155 447 3515 +PR.C 301 913 8967 +QUERY.C 51 144 1229 +RDXCNVRT.C 49 141 1029 +REMTAB.C 63 177 1703 +RM_ALL.C 222 655 6003 +ROMAN.C 97 192 1752 +SETIMETO.C 64 160 1303 +SETVOL.C 222 626 5124 +SPLIT.C 71 207 1829 +STRIPEOF.C 61 125 1412 +STUB.C 115 396 3331 +SUNRISET.C 507 2443 21206 +TAIL.C 181 467 4541 +TODAYBAK.C 98 270 2172 +TOUCH.C 63 202 1916 +TREEDIR.C 53 159 1252 +UUENCODE.C 146 448 3077 +UUDECODE.C 41 119 1075 +WC.C 66 161 1378 +WHERE.C 132 405 3434 +JGREP.C 178 481 4519 +GREP.C 567 1755 15359 +--------------------------------- ------- ------- ------- +Total (367 files) 39137 139917 1122625 diff --git a/reference/C/CONTRIB/SNIP/sound.c b/reference/C/CONTRIB/SNIP/sound.c new file mode 100755 index 0000000..2979ce5 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/sound.c @@ -0,0 +1,30 @@ +/* +** SOUND.C +** +** Original Copyright 1988-1991 by Bob Stout as part of +** the MicroFirm Function Library (MFL) +** +** This subset version is functionally identical to the +** version originally published by the author in Tech Specialist +** magazine and is hereby donated to the public domain. +*/ + +#include "sound.h" + +void soundon(void) +{ + short value; + + value = inp(SCNTRL); + value |= SOUNDON; + outp(SCNTRL, value); +} + +void soundoff(void) +{ + short value; + + value = inp(SCNTRL); + value &= SOUNDOFF; + outp(SCNTRL, value); +} diff --git a/reference/C/CONTRIB/SNIP/sound.h b/reference/C/CONTRIB/SNIP/sound.h new file mode 100755 index 0000000..fecaf60 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/sound.h @@ -0,0 +1,181 @@ +/* +** SOUND.H +** +** Original Copyright 1988-1991 by Bob Stout as part of +** the MicroFirm Function Library (MFL) +** +** This subset version is functionally identical to the +** version originally published by the author in Tech Specialist +** magazine and is hereby donated to the public domain. +*/ + +#if defined(__ZTC__) + #include <int.h> + #undef int_on + #undef int_off +#elif defined(__TURBOC__) + #define int_on enable + #define int_off disable + #ifndef inp + #define inp inportb + #endif + #ifndef outp + #define outp outportb + #endif +#else /* assume MSC/QC */ + #include <conio.h> + #define int_on _enable + #define int_off _disable + #define getvect _dos_getvect + #define setvect _dos_setvect +#endif + +/* defines for mktone() update parameter: */ + +#define ON 0 /* turn the speaker on */ +#define UPDATE 1 /* sound is on, just change freq */ +#define TOGGLE 2 /* for delay use, turn on, then off */ + +/* port equates */ + +#define SCNTRL 0x61 /* sound control port */ +#define SOUNDON 0x03 /* bit mask to enable speaker */ +#define SOUNDOFF 0xfc /* bit mask to disable speaker */ +#define C8253 0x43 /* port address to control 8253 */ +#define SETIMER 0xb6 /* tell 8253 to expect freq data next */ +#define F8253 0x42 /* frequency address on 8253 */ + +/* frequency equates (muscical scale) */ +/* digit in label is octave number, S indicates Sharp (#) */ + +#define C0 36489 +#define CS0 34445 +#define D0 32512 +#define DS0 30673 +#define E0 28961 +#define F0 27329 +#define FS0 25804 +#define G0 24351 +#define GS0 22981 +#define A0 21694 +#define AS0 20473 +#define B0 19326 + +#define C1 18244 +#define CS1 17218 +#define D1 16251 +#define DS1 15340 +#define E1 14480 +#define F1 13668 +#define FS1 12899 +#define G1 12175 +#define GS1 11493 +#define A1 10847 +#define AS1 10238 +#define B1 9663 + +#define C2 9121 +#define CS2 8609 +#define D2 8126 +#define DS2 7670 +#define E2 7239 +#define F2 6833 +#define FS2 6450 +#define G2 6088 +#define GS2 5746 +#define A2 5424 +#define AS2 5119 +#define B2 4832 + +#define C3 4561 +#define CS3 4305 +#define D3 4063 +#define DS3 3835 +#define E3 3620 +#define F3 3417 +#define FS3 3225 +#define G3 3044 +#define GS3 2873 +#define A3 2712 +#define AS3 2560 +#define B3 2416 + +#define C4 2280 +#define CS4 2152 +#define D4 2032 +#define DS4 1917 +#define E4 1810 +#define F4 1708 +#define FS4 1612 +#define G4 1522 +#define GS4 1437 +#define A4 1356 +#define AS4 1280 +#define B4 1210 + +#define C5 1140 +#define CS5 1076 +#define D5 1016 +#define DS5 959 +#define E5 905 +#define F5 854 +#define FS5 806 +#define G5 761 +#define GS5 718 +#define A5 678 +#define AS5 640 +#define B5 604 + +#define C6 570 +#define CS6 538 +#define D6 508 +#define DS6 479 +#define E6 449 +#define F6 427 +#define FS6 403 +#define G6 380 +#define GS6 359 +#define A6 339 +#define AS6 320 +#define B6 302 + +#define C7 285 +#define CS7 269 +#define D7 254 +#define DS7 240 +#define E7 226 +#define F7 214 +#define FS7 202 +#define G7 190 +#define GS7 180 +#define A7 169 +#define AS7 160 +#define B7 151 + +#define C8 143 + +#define REST 0 + +typedef struct +{ + unsigned int freq; + unsigned int duration; +} NOTE; + +#if __cplusplus + extern "C" { +#endif + +void mktone(int, int, unsigned), + dosound(int), + soundon(void), + soundoff(void), + playb_close(void); + +int playb_note(unsigned, unsigned); + +NOTE *playb_open(unsigned); + +#if __cplusplus + } +#endif diff --git a/reference/C/CONTRIB/SNIP/soundex.c b/reference/C/CONTRIB/SNIP/soundex.c new file mode 100755 index 0000000..b9685f8 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/soundex.c @@ -0,0 +1,43 @@ +/* +** from Bob Jarvis +*/ + +#include <stdio.h> +#include <ctype.h> + +char *soundex(char *instr, char *outstr) +{ /* ABCDEFGHIJKLMNOPQRSTUVWXYZ */ + char *table = "01230120022455012623010202"; + int count = 0; + + while(!isalpha(instr[0]) && instr[0]) + ++instr; + + if(!instr[0]) /* Hey! Where'd the string go? */ + return(NULL); + + if(toupper(instr[0]) == 'P' && toupper(instr[1]) == 'H') + { + instr[0] = 'F'; + instr[1] = 'A'; + } + + *outstr++ = (char)toupper(*instr++); + + while(*instr && count < 5) + { + if(isalpha(*instr) && *instr != *(instr-1)) + { + *outstr = table[toupper(instr[0]) - 'A']; + if(*outstr != '0') + { + ++outstr; + ++count; + } + } + ++instr; + } + + *outstr = '\0'; + return(outstr); +} diff --git a/reference/C/CONTRIB/SNIP/speed.c b/reference/C/CONTRIB/SNIP/speed.c new file mode 100755 index 0000000..db77f05 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/speed.c @@ -0,0 +1,155 @@ +/******** CALCULATE I/O PERFORMANCE TO NUL FILE ********/ + +#include <assert.h> +#include <dos.h> +#include <stdio.h> +#include <stdlib.h> + +#define CHK 100 /* speed factor */ + +long ticks(long tick) /* GET BIOS TIME TICK */ +{ + union REGS reg; + reg.h.ah=0; + int86(0x1A, ®, ®); + return ((long)reg.x.cx<<16)+reg.x.dx-tick; +} + +long time_it(void(*func)(void)) +{ + long t = ticks(0L); + (*func)(); + return ticks(t); +} + +void show_it(long t) +{ + long lquot, lrem; + t = (t*1000/182+5)/10; + lquot = t/10; + lrem = t%10; + printf("%3ld.%02d sec", lquot, (int)lrem); +} + +void t_printf(void) +{ + register FILE *fp; + register unsigned u; + + fp = fopen("NUL", "wt"); + assert(fp != NULL); + for (u=0; u<50*CHK; ++u) + fprintf(fp, "Now is %d time for %d little indians\n", 123, -456); + fclose(fp); +} + +void b_printf(void) +{ + register FILE *fp; + register unsigned u; + + fp = fopen("NUL", "wb"); + assert(fp != NULL); + for (u=0; u<50*CHK; ++u) + fprintf(fp, "Now is %d time for %d little indians\n", 123, -456); + fclose(fp); +} + +void tu_printf(void) +{ + register FILE *fp; + register unsigned u; + + fp = fopen("NUL", "wt"); + assert(fp != NULL); + setbuf(fp, NULL); + for (u=0; u<5*CHK; ++u) + fprintf(fp, "Now is %d time for %d little indians\n", 123, -456); + fclose(fp); +} + +void bu_printf(void) +{ + register FILE *fp; + register unsigned u; + + fp = fopen("NUL", "wb"); + assert(fp != NULL); + setbuf(fp, NULL); + for (u=0; u<5*CHK; ++u) + fprintf(fp, "Now is %d time for %d little indians\n", 123, -456); + fclose(fp); +} + +void t_write(void) +{ + register FILE *fp; + register unsigned u; + + fp = fopen("NUL", "wt"); + assert(fp != NULL); + for (u=0; u<250*CHK; ++u) + fwrite("Now is the time for all good men to come\n", 41, 1, fp); + fclose(fp); +} + +void b_write(void) +{ + register FILE *fp; + register unsigned u; + + fp = fopen("NUL", "wb"); + assert(fp != NULL); + for (u=0; u<500*CHK; ++u) + fwrite("Now is the time for all good men to come\n", 41, 1, fp); + fclose(fp); +} + +void tu_write(void) +{ + register FILE *fp; + register unsigned u; + + fp = fopen("NUL", "wt"); + assert(fp != NULL); + setbuf(fp, NULL); + for (u=0; u<100*CHK; ++u) + fwrite("Now is the time for all good men to come\n", 41, 1, fp); + fclose(fp); +} + +void bu_write(void) +{ + register FILE *fp; + register unsigned u; + + fp = fopen("NUL", "wb"); + assert(fp != NULL); + setbuf(fp, NULL); + for (u=0; u<200*CHK; ++u) + fwrite("Now is the time for all good men to come\n", 41, 1, fp); + fclose(fp); +} + +main(void) +{ + show_it(time_it(t_printf)); + printf(": time for text printf buffered\n"); + show_it(time_it(b_printf)); + printf(": time for binary printf buffered\n"); + show_it(time_it(tu_printf)); + printf(": time for text printf unbuffered\n"); + show_it(time_it(bu_printf)); + printf(": time for binary printf unbuffered\n"); + + show_it(time_it(t_write)); + printf(": time for text write buffered\n"); + show_it(time_it(b_write)); + printf(": time for binary write buffered\n"); + show_it(time_it(tu_write)); + printf(": time for text write unbuffered\n"); + show_it(time_it(bu_write)); + printf(": time for binary write unbuffered\n"); + + return 0; +} diff --git a/reference/C/CONTRIB/SNIP/spin.c b/reference/C/CONTRIB/SNIP/spin.c new file mode 100755 index 0000000..785bdbf --- /dev/null +++ b/reference/C/CONTRIB/SNIP/spin.c @@ -0,0 +1,29 @@ +/* +** Miscellaneous text spinners demonstration +** +** public domain by Jon Guthrie, Bob Stout, and others +*/ + +#include <stdio.h> + +#define DURATION 500 /* Length of demo */ +#define SSLOWDOWN 5 /* Make spinner look ok */ +#define TSLOWDOWN 10 /* Make target look ok */ + +main() +{ + unsigned i; + char spinner[] = "|/-\\", target[] = ".oO"; + + for (i = 0; i < DURATION; ++i) + { + unsigned scount = i / SSLOWDOWN, tcount = i / TSLOWDOWN; + unsigned scountdown = DURATION / SSLOWDOWN; + unsigned tcountdown = DURATION / TSLOWDOWN; + + printf("CW %c ... CCW %c ... Explode %c ... Implode%c\r", + spinner[scount & 3], spinner[(scountdown - scount) & 3], + target[tcount % 3], target[(tcountdown - tcount) % 3]); + } + return 0; +} diff --git a/reference/C/CONTRIB/SNIP/split.c b/reference/C/CONTRIB/SNIP/split.c new file mode 100755 index 0000000..cd3b978 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/split.c @@ -0,0 +1,71 @@ +/* +** SPLIT.C - A utility to split large text files into smaller files +** +** public domain by Bob Stout +** +** uses PSPLIT.C from SNIPPETS +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#ifdef __TURBOC__ + #define FAR far +#else + #define FAR _far +#endif + +void psplit(char *, char *, char *, char *, char *); + +int main(int argc, char *argv[]) +{ + long newsize = 32L * 1024L; + size_t seq = 0; + char fname[FILENAME_MAX]; + FILE *from; + + if (2 > argc) + { + puts("SPLIT big_file [size_in_K]\n"); + puts("creates files of the same name, " + "but with numeric extensions"); + puts("a maximum file size may be specified for new files"); + return EXIT_SUCCESS; + } + if (2 < argc) + { + newsize = atol(argv[2]); + newsize <<= 10; + } + if (NULL == (from = fopen(argv[1], "r"))) + { + printf("\aSPLIT: error - can't open %s\n", argv[1]); + return EXIT_FAILURE; + } + psplit(argv[1], NULL, NULL, fname, NULL); + while (!feof(from)) + { + char newname[FILENAME_MAX], buf[1024]; + FILE *to; + long bytes; + + sprintf(newname, "%s.%03d", fname, seq++); + if (NULL == (to = fopen(newname, "w"))) + { + printf("\aSPLIT: error - can't write %s\n", newname); + return EXIT_FAILURE; + } + for (bytes = 0L; !feof(from) && (bytes < newsize); ) + { + if (fgets(buf, 1023, from)) + { + fputs(buf, to); + bytes += (long)strlen(buf); + } + } + fclose(to); + printf("%s written\n", newname); + } + return EXIT_SUCCESS; +} diff --git a/reference/C/CONTRIB/SNIP/srchfile.c b/reference/C/CONTRIB/SNIP/srchfile.c new file mode 100755 index 0000000..d55fb88 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/srchfile.c @@ -0,0 +1,225 @@ +/* +** SRCHFILE.C - Functions for searching files +** +** public domain by Bob Stout +** +** Note: Although this snippet demonstrates some useful techniques, even +** the fast text searching algorithm used can't provide particularly +** good performance. Left as an exercise for the user is to perform +** explicit buffering using fread() rather than fgets() as is used +** here. See CHBYTES.C in SNIPPETS for how to perform searches in +** user-managed buffers. +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#define SUCCESS 0 + +/* +** Allocate a big buffer, use it to buffer a specified stream +*/ + +static size_t fsetup(FILE *fp, size_t minbuf) +{ + register size_t bufsize; + register char *buffer; + + /* Allocate the largest buffer we can */ + + for (bufsize = 0x4000; bufsize >= minbuf; bufsize >>= 1) + { + if (NULL != (buffer = (char *) malloc(bufsize))) + break; + } + if (NULL == buffer) + return 0; + + /* Use the buffer to buffer the file */ + + if (SUCCESS == setvbuf(fp, buffer, _IOFBF, bufsize)) + return bufsize; + else return 0; +} + +/* +** Search a file for a pattern match (forward) +** +** Arguments: FILE pointer +** pattern to search for +** size of pattern +** find Nth occurance +** +** Returns: -1L if pattern not found +** -2L in case of error +*/ + +long ffsearch(FILE *fp, const char *pattern, const size_t size, int N) +{ + long pos = -2L, tempos = 0L; + char *sbuf, *p; + size_t i, skip; + int ch = 0; + + /* Allocate a search buffer */ + + if (NULL == (sbuf = (char *)malloc(size - 1))) + goto FDONE; + + /* Buffer the file and position us within it */ + + if (0 == fsetup(fp, size)) + goto FDONE; + pos = -1L; + fseek(fp, 0L, SEEK_SET); + + /* Set up for smart searching */ + + if (1 < strlen(pattern) && NULL != (p = strchr(pattern + 1, *pattern))) + skip = p - (char *)pattern; + else skip = strlen(pattern); + + /* Look for the pattern */ + + while (EOF != ch) + { + if (EOF == (ch = fgetc(fp))) + break; + if ((int)*pattern == ch) + { + tempos = ftell(fp); + if (size - 1 > fread(sbuf, sizeof(char), size - 1, fp)) + goto FDONE; + if (SUCCESS == memcmp(sbuf, &pattern[1], size - 1)) + { + if (0 == --N) + { + pos = tempos - 1L; + goto FDONE; + } + } + fseek(fp, tempos + skip, SEEK_SET); + } + } + + /* Clean up and leave */ + +FDONE: + free(sbuf); + return pos; +} + +/* +** Search a file for a pattern match (backwards) +** +** Arguments: FILE pointer +** pattern to search for +** size of pattern +** find Nth occurance +** +** Returns: -1L if pattern not found +** -2L in case of error +*/ + +long rfsearch(FILE *fp, const char *pattern, const size_t size, int N) +{ + long pos = -2L, tempos; + char *sbuf, *p; + size_t i, skip; + int ch = 0; + + /* Allocate a search buffer */ + + if (NULL == (sbuf = (char *)malloc(size - 1))) + goto RDONE; + + /* Buffer the file and position us within it */ + + if (0 == fsetup(fp, size)) + goto RDONE; + pos = -1L; + fseek(fp, -1L, SEEK_END); + tempos = ftell(fp) - strlen(pattern); + + /* Set up for smart searching */ + + if (1 < strlen(pattern) && NULL != (p = strrchr(pattern + 1, *pattern))) + skip = strlen(pattern) - (p - (char *)pattern); + else skip = strlen(pattern); + + /* Look for the pattern */ + + while (0L <= tempos) + { + fseek(fp, tempos, SEEK_SET); + if (EOF == (ch = fgetc(fp))) + break; + if ((int)*pattern == ch) + { + if (size - 1 <= fread(sbuf, sizeof(char), size - 1, fp)) + { + if (SUCCESS == memcmp(sbuf, &pattern[1], size - 1)) + { + if (0 == --N) + { + pos = tempos; + goto RDONE; + } + } + } + tempos -= skip; + } + else --tempos; + } + + /* Clean up and leave */ + +RDONE: + free(sbuf); + return pos; +} + +#ifdef TEST + +int main(int argc, char *argv[]) +{ + long pos; + int N = 1; + size_t size = strlen(argv[1]); + char buf[256], *fname = "SRCHFILE.C"; + FILE *fp; + + if (2 > argc) + { + puts("Usage: SRCHFILE string [N] [file]"); + puts("where: N = find Nth occurance"); + puts(" If file is specified, N must be given"); + return EXIT_FAILURE; + } + + if (2 < argc) + N = atoi(argv[2]); + + if (3 < argc) + fname = strupr(argv[3]); + + fp = fopen(fname, "r"); + printf("ffsearch(%s, %s) returned %ld\n", fname, argv[1], + pos = ffsearch(fp, argv[1], size, N)); + fseek(fp, pos, SEEK_SET); + fgets(buf, 256, fp); + printf("...which contains \"%s\"\n\n", buf); + fclose(fp); + + fp = fopen(fname, "rb"); + printf("rfsearch(%s, %s) returned %ld\n", fname, argv[1], + pos = rfsearch(fp, argv[1], size, N)); + fseek(fp, pos, SEEK_SET); + fgets(buf, 256, fp); + printf("...which contains \"%s\"\n\n", buf); + fclose(fp); + return EXIT_SUCCESS; +} + +#endif /* TEST */ diff --git a/reference/C/CONTRIB/SNIP/sstrcpy.c b/reference/C/CONTRIB/SNIP/sstrcpy.c new file mode 100755 index 0000000..fd8531b --- /dev/null +++ b/reference/C/CONTRIB/SNIP/sstrcpy.c @@ -0,0 +1,13 @@ +#include <string.h> + +char *sstrcpy(char *to, char *from) +{ + memmove(to, from, 1+strlen(from)); + return to; +} + +char *sstrcat(char *to, char *from) +{ + sstrcpy(to + strlen(to), from); + return to; +} diff --git a/reference/C/CONTRIB/SNIP/stats.c b/reference/C/CONTRIB/SNIP/stats.c new file mode 100755 index 0000000..c17f8d6 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/stats.c @@ -0,0 +1,53 @@ +/****************************************************************/ +/* */ +/* Collect file statistics */ +/* */ +/* Public domain demo program for analyzing encrypted */ +/* files. By: Bob Stout */ +/* */ +/****************************************************************/ + +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include <assert.h> + +main(int argc, char *argv[]) +{ + int i, ch, hist = 0; + long n = 0L; + double mean = 0., stdev = 0., ftmp; + static unsigned bins[256]; + FILE *infile; + + assert(infile = fopen(argv[1], "rb")); + while (!feof(infile)) + { + if (EOF == (ch = fgetc(infile))) + break; + bins[ch] += 1; + ++n; + } + fclose(infile); + for (i = 0; i < 256; ++i) + { + mean += (double)(bins[i]); + if (bins[i]) + ++hist; + } + mean /= 256.; + for (i = 0; i < 256; ++i) + { + ftmp = (double)(bins[i]) - mean; + stdev += (ftmp * ftmp); + } + ftmp = stdev / 255.; + stdev = sqrt(ftmp); + printf("%ld Characters were read from %s\n" + "There are an average of %f occurances of each character\n" + "%d Characters out of 256 possible were used\n" + "The standard deviation is %f\n" + "The coefficient of variation is %f%%\n", + n, argv[1], mean, hist, stdev, (100. * stdev) / mean); + return EXIT_SUCCESS; +} diff --git a/reference/C/CONTRIB/SNIP/storage.typ b/reference/C/CONTRIB/SNIP/storage.typ new file mode 100755 index 0000000..1203112 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/storage.typ @@ -0,0 +1,78 @@ + STORAGE TYPES + + A C language crib sheet from Jeff Galbraith + + +int x; + - x is an int. + +int *x; + - x is a pointer to an int. + +int **x; + - x is a pointer to a pointer to an int. + +const int x; + - x is a const int (constant integer). + +const int *x; + - x is a pointer to a const int. The value of x may change, but + the integer that it points to not be changed. In other words, + x cannot be used to alter the value to which it points. + +int *const x; + - x is a constant pointer to an int. The value may not change, + but the integer that it points to may change. In other words, + x will always point at the same location, but the contents may + vary. + +const int *const x; + - x is a constant pointer to a constant integer. The value of x + may not change, and the integer that it points to may not + change. In other words, x will always point at the same + location, which cannot be modified via x. + +int x[]; + - x is an array of int. + +int x[99]; + - x is an array of 99 int's. + +int *x[]; + - x is an array of pointers to int. + +int (*x)[]; + - x is a pointer to an array of int. + +int *(*x)[]; + - x is a pointer to an array of pointers to int. + +int F(); + - F is a function returning int. + +int *F(); + - F is a function returning a pointer to int. + +int (*x)(); + - x is a pointer to a function returning int. + +int (*x[99])(); + - x is an array of 99 pointers to functions returning int. + +int (*F())(); + - F is a function returning a pointer to a function returning int. + +int *(*F())(); + - F is a function returning a pointer to a function returning a + pointer to an int. + +int (*F())[]; + - F is a function returning a pointer to an array of int. + +int (*(*F())[])(); + - F is a function returning a pointer to an array of pointers to + functions returning int. + +int *(*(*F())[])(); + - F is a function returning a pointer to an array of pointers to + functions returning a pointer to int. diff --git a/reference/C/CONTRIB/SNIP/stptok.c b/reference/C/CONTRIB/SNIP/stptok.c new file mode 100755 index 0000000..25c7faf --- /dev/null +++ b/reference/C/CONTRIB/SNIP/stptok.c @@ -0,0 +1,38 @@ +/* +** stptok() -- public domain by Ray Gardner, modified by Bob Stout +** +** You pass this function a string to parse, a buffer to receive the +** "token" that gets scanned, the length of the buffer, and a string of +** "break" characters that stop the scan. It will copy the string into +** the buffer up to any of the break characters, or until the buffer is +** full, and will always leave the buffer null-terminated. It will +** return a pointer to the first non-breaking character after the one +** that stopped the scan. +*/ + +#include <string.h> +#include <stdlib.h> + +char *stptok(const char *s, char *tok, size_t toklen, char *brk) +{ + char *lim, *b; + + if (!*s) + return NULL; + + lim = tok + toklen - 1; + while ( *s && tok < lim ) + { + for ( b = brk; *b; b++ ) + { + if ( *s == *b ) + { + *tok = 0; + return (char *)s; + } + } + *tok++ = *s++; + } + *tok = 0; + return (char *)s; +} diff --git a/reference/C/CONTRIB/SNIP/str.cpp b/reference/C/CONTRIB/SNIP/str.cpp new file mode 100755 index 0000000..df4f118 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/str.cpp @@ -0,0 +1,303 @@ +// +// Implements simple string class 'str' +// + +# include "str.h" +# include <string.h> +# include <memory.h> +# if defined( _MSC_VER ) +# pragma warning(disable:4505) +# endif + +# define STDLEN 32 + +extern "C" void * malloc (unsigned sz); +extern "C" void free (void * ptr); + +# if defined( PLACEMENT_NEW_BUG ) + +inline void * +operator new (unsigned sz, short allocsz) +{ + return malloc (sz + allocsz); +} + +# else + +void * +refstr::operator new (unsigned sz, short allocsz) +{ + return malloc (sz + allocsz); +} + +# endif + +void +str::_strinit (char const * s, short len, short siz) +{ + if (len < 0) + len = (short) ((s) ? strlen (s) : 0); + if (siz < 0) + siz = STDLEN; + if (siz < len + 1) + siz = short(len + 1); + strdata = new(siz) refstr(len, siz); + if (s && len) + memcpy (c_ptr(), s, len); +} + + // Called whenever string is to be modified or grown +int +str::_chksize (short sz) +{ + refstr * old = 0; + if (strdata->_refs > 1) // Need to dup memory + --strdata->_refs; // Dec existing string reference + else if (sz >= size()) + old = strdata; + else + return 0; + _strinit (c_ptr(), length(), sz); + delete old; + return 1; +} + +str & +str::operator= (str const & s) +{ + if (&s != this) + { + if (!--strdata->_refs) + delete strdata; + strdata = s.strdata; + ++strdata->_refs; + } + return *this; +} + +str & +str::operator= (char const * s) +{ + if (s != c_ptr()) + { + short len = (short) strlen (s); + _chksize (len); + memcpy (c_ptr(), s, len + 1); + strdata->_length = len; + } + return *this; +} + +str & +str::operator= (char c) +{ + _chksize (1); + *c_ptr() = c; + strdata->_length = 1; + return *this; +} + +short +str::insert (short pos, char const * s, short len) +{ + if (len < 0) + len = (short) strlen (s); + if (len) + { + short leng = strdata->_length; + if (pos < 0 || pos > leng) + pos = leng; + _chksize (short(leng + len)); + char * buf = c_ptr(); + if (pos < leng) + memmove (buf + pos + len, buf + pos, leng - pos); + memcpy (buf + pos, s, len); + strdata->_length += len; + } + return length(); +} + +short +str::remove (short pos, short len) +{ + if (pos >= 0 && pos < length()) + { + short leng = strdata->_length; + if (len < 0 || (pos + len) > leng) + len = short(leng - pos); + if (len) + { + _chksize (0); + char * buf = c_ptr(); + memcpy (buf + pos, buf + pos + len, leng - (pos + len)); + strdata->_length -= len; + } + } + return length(); +} + +short +str::replace (short pos, char const * s, short clen, short len) +{ + if (pos >= 0) + { + short leng = strdata->_length; + if (clen < 0 || (pos + clen) > leng) + clen = short(leng - pos); + if (len < 0) + len = (short) strlen (s); + if (pos > leng) + pos = leng; + _chksize (short(leng - clen + len)); + char * buf = c_ptr(); + if (clen != len && clen) + memmove (buf + pos + len, buf + pos + clen, + leng - (pos + clen - len)); + if (len) + memcpy (buf + pos, s, len); + strdata->_length += short(len - clen); + } + return length(); +} + + +str & +str::left (short len, char padch) +{ + if (len < 0) + return right (short(-len), padch); + short leng = strdata->_length; + if (len != leng) + { + _chksize (len); + if (len > leng) + memset (strdata->ptr() + leng, padch, leng - len); + strdata->_length = len; + } + return *this; +} + +str & +str::right (short len, char padch) +{ + if (len < 0) + return left(-1, padch); + short leng = strdata->_length; + if (len != leng) + { + _chksize (len); + if (len > leng) + { + char * buf = strdata->ptr(); + memmove (buf + len - leng, buf, leng); + memset (buf, padch, len - leng); + } + strdata->_length = len; + } + return *this; +} + +str & +str::mid (short pos, short len, char padch) +{ + if (pos <= 0) + return left(len, padch); + short leng = strdata->_length; + if (pos > leng) + pos = leng; + if (leng < len) // Are we padding? + { + _chksize (len); + char * buf = strdata->ptr(); + short nlen = short((len - (leng - pos)) / 2); + if (nlen > 0) + { + memmove (buf, buf + pos, leng - pos); + memset (buf + leng - pos, padch, nlen); + strdata->_length -= short(pos - nlen); + } + } + return right (len, padch); +} + + +int +str::_concat (char const * s, short len) +{ + if (len < 0) + len = (short) strlen (s); + if (len) + { + _chksize (short(len + length())); + memcpy (c_ptr() + length(), s, len); + strdata->_length += len; + } + return length(); +} + +short +str::removech (char const * clist) +{ + short result = 0; + if (*clist) + { + char * buf, * sub; + buf = sub = strdata->ptr(); + short nlen = strdata->_length; + for (short i = 0; i < nlen; ++i) + { + if (strchr (clist, *buf) == 0) + { + if (result) + *sub = *buf; + ++sub; + } + else + { + if (!result) + _chksize (0); + ++result; + } + ++buf; + } + strdata->_length = short(nlen - result); + } + return result; +} + +short +str::countch (char const * clist) +{ + short result = 0; + if (*clist) + { + char * buf = strdata->ptr(); + short nlen = strdata->_length; + for (short i = 0; i < nlen; ++i, ++buf) + if (strchr (clist, *buf) != 0) + ++result; + } + return result; +} + + +str +left (str const & s, short len, char padch) +{ + str n(s); + return n.left(len, padch); +} + +str +right (str const & s, short len, char padch) +{ + str n(s); + return n.right(len, padch); +} + +str +mid (str const & s, short pos, short len, char padch) +{ + str n(s); + return n.mid(pos, len, padch); +} diff --git a/reference/C/CONTRIB/SNIP/str.doc b/reference/C/CONTRIB/SNIP/str.doc new file mode 100755 index 0000000..c2a54c1 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/str.doc @@ -0,0 +1,47 @@ +Bear in mind that this is an intentionally simple and plain string class, +devoid of many features which might be found in a more complete +implementation. + +The reason I say 'intentionally' is purely because it was written for a +specific set of uses than to be the be-all and everything-including-your- +kitchen-sink-string-class. In particular, the aims I had in mind were: + + 1. Portable, + + 2. Small but efficient - where sizeof(str) == sizeof(char *) in + almost all C++ implementations, + + 3. Doesn't rely upon, but allows for, NUL terminators, so avoids + lots of redundant length calculations as is common in C. The + library attempts to use memory operations rather than C string + operations where possible, + + 4. As much as possible is implemented in-line for speed. All common + operations are centralised into a 'core' set of private functions. + + 5. Copy constructors and assignment are cheap operations by use of + reference counting. This makes passing objects by value very cheap + (requires no as few as possible memory allocations / copying of + string data), and is conservative with memory. + + 6. Should be easily exchanged with char*. + + 7. Memory management of strings made possible by use of a single + memory allocation function for string data (easily replaced or + enhanced) + + 8. Uses absolutely no third party classes, so is stand-alone, making + it highly reusable, + + 9. Requires no additional include files from the standard library. + + 10. Avoids use of cast operators for char const * and therefore + prevents problems caused by creation of temporaries (these can + also occur with member c_str(), but at least you have to explicitly + invoke it rather than causing a temporary to be used in a dangerous + manner without notification). + + + cheers, + David Nugent + Moderator ('93-'94) of the FidoNet C++ international EchoMail conference diff --git a/reference/C/CONTRIB/SNIP/str.h b/reference/C/CONTRIB/SNIP/str.h new file mode 100755 index 0000000..07faead --- /dev/null +++ b/reference/C/CONTRIB/SNIP/str.h @@ -0,0 +1,322 @@ +// +// Simple string class +// Public domain +// +// Written by david nugent +// davidn@csource.pronet.com +// 3:632/348@fidonet +// + +# if !defined( _str_h ) +# define _str_h 1 + +# if defined( __BORLANDC__ ) && ( __BORLANDC__ <= 0x0300 ) +# define PLACEMENT_NEW_BUG +# define SIGNED_CHAR_BUG +# endif + + +struct refstr +{ + short _size; + short _length; + short _refs; + refstr (short length, short size) + : _length(length), _size(size), _refs(1) + {} + ~refstr (void) {} +# if !defined( PLACEMENT_NEW_BUG ) + void * operator new(unsigned sz, short allocsz); +# endif + char * ptr (void) + { + return ((char *)this) + sizeof(refstr); + } +}; + + + + +class str +{ + + public: + + // constructors/destructors + + str (void) + { + _strinit(); + } + + str (char const * s, short len =-1) + { + _strinit(s, len, -1); + } + + str (unsigned char const * s, short len =-1) + { + _strinit((char const *)s, len, -1); + } +# if !defined( SIGNED_CHAR_BUG ) + str (signed char const * s, short len =-1) + { + _strinit((char const *)s, len, -1); + } +# endif + + str (char c) + { + _strinit (&c, 1, -1); + } + + str (unsigned char c) + { + _strinit ((char const *)&c, 1, -1); + } +# if !defined( SIGNED_CHAR_BUG ) + str (signed char c) + { + _strinit ((char const *)&c, 1, -1); + } +# endif + str (str const & s) + : strdata(s.strdata) + { + ++strdata->_refs; + } + + ~str (void) + { + if (!--strdata->_refs) + delete strdata; + } + + // assignment + + str & operator= (str const & s); + str & operator= (char const * s); + str & operator= (char c); + + str & operator= (unsigned char const * s) + { + return operator= ((char const *)s); + } +# if !defined( SIGNED_CHAR_BUG ) + str & operator= (signed char const * s) + { + return operator= ((char const *)s); + } +# endif + + // primitive members + + short length (void) const + { + return strdata->_length; + } + + short size (void) const + { + return strdata->_size; + } + + // operators + + str & operator<< (char const * s) // concatenate + { + _concat (s); + return *this; + } + + str & operator<< (unsigned char const * s) + { + _concat ((char const *)s); + return *this; + } +# if !defined( SIGNED_CHAR_BUG ) + str & operator<< (signed char const * s) + { + _concat ((char const *)s); + return *this; + } +# endif + str & operator<< (str const & s) + { + _concat (s); + return *this; + } + + str & operator<< (char c) + { + _concat (c); + return *this; + } + + str & operator<< (unsigned char c) + { + _concat (c); + return *this; + } + +# if !defined( SIGNED_CHAR_BUG ) + str & operator<< (signed char c) + { + _concat (c); + return *this; + } +# endif + + char & operator[] (short pos) + { + if (pos < 0 || pos >= strdata->_length) + { + char * buf = c_ptr() + length(); + *buf = 0; + return *buf; + } + return c_ptr()[pos]; + } + + char * c_ptr (void) const // not necessarily NUL terminated! + { // Use with caution... + return strdata->ptr(); + } + + char const * c_str (void) const // return char* + { + char * buf = c_ptr(); + buf[strdata->_length] = 0; + return buf; + } + + unsigned char const * u_str (void) const + { + return (unsigned char const *)c_str(); + } + + // manipulators + + short insert (short pos, char const * s, short len =-1); + + short insert (short pos, str const & s) + { + return insert (pos, s.c_ptr(), s.length()); + } + + short insert (short pos, unsigned char const * s, + short len =-1) + { + return insert (pos, (char const *)s, len); + } +# if !defined( SIGNED_CHAR_BUG ) + short insert (short pos, signed char const * s, + short len =-1) + { + return insert (pos, (char const *)s, len); + } +# endif + short insert (short pos, char c) + { + return insert (pos, &c, 1); + } + + short insert (short pos, unsigned char c) + { + return insert (pos, (char const *)&c, 1); + } +# if !defined( SIGNED_CHAR_BUG ) + short insert (short pos, signed char c) + { + return insert (pos, (char const *)&c, 1); + } +# endif + + short remove (short pos =0, short len =-1); + + short replace (short pos, char const * s, short clen =-1, + short len =-1); + + short replace (short pos, str & s, short clen =-1) + { + return replace (pos, s.c_ptr(), clen, s.length()); + } + + short replace (short pos, unsigned char const * s, + short clen =-1, short len =-1) + { + return replace (pos, (char const *)s, clen, len); + } +# if !defined( SIGNED_CHAR_BUG ) + short replace (short pos, signed char const * s, + short clen =-1, short len =-1) + { + return replace (pos, (char const *)s, clen, len); + } +# endif + short replace (short pos, char c, short clen =-1) + { + return replace (pos, &c, clen, 1); + } + + short replace (short pos, unsigned char c, short clen =-1) + { + return replace (pos, (char const *)&c, clen, 1); + } +# if !defined( SIGNED_CHAR_BUG ) + short replace (short pos, signed char c, short clen =-1) + { + return replace (pos, (char const *)&c, clen, 1); + } +# endif + + str & left (short len, char padch =' '); + str & right (short len, char padch =' '); + str & mid (short pos, short len, char padch =' '); + + short removech (char const * clist ="\r\n"); + short countch (char const * clist); + + protected: + + refstr * strdata; + + // Check to see if big enough for size + int _chksize (short sz =0); + + int _concat (char const * s, short len =-1); + + int _concat (str const & s) + { + return _concat (s.c_ptr(), s.length()); + } + + int _concat (char ch) + { + return _concat (&ch, 1); + } + + int _concat (unsigned char const * s, short len =-1) + { + return _concat ((char const *)s, len); + } +# if !defined( SIGNED_CHAR_BUG ) + int _concat (signed char const * s, short len =-1) + { + return _concat ((char const *)s, len); + } +# endif + + private: + // Common constructor + void _strinit (char const * s =0, short slen =0, + short siz =-1); + +}; + + +str left (str const & s, short len, char padch =' '); +str right (str const & s, short len, char padch =' '); +str mid (str const & s, short pos, short len, char padch =' '); + +# endif diff --git a/reference/C/CONTRIB/SNIP/str27seg.c b/reference/C/CONTRIB/SNIP/str27seg.c new file mode 100755 index 0000000..f36e841 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/str27seg.c @@ -0,0 +1,148 @@ +/* +** STR27SEG.C - Convert numeric strings to 7-segment strings. +** +** Public domain by Bob Stout +** +** Input: A string (NUL-delimited char array) containing only digits +** ('0' - '9' chars). +** +** Output: The same string with each digit converted to a 7-segment +** representation. Returns NULL on error. +*/ + +#include <stdio.h> +#include <ctype.h> + +#define CAST(new_type,old_object) (*((new_type *)&old_object)) +#define DISP(str) fputs((str), stdout) + +/* +** Define the bit significance +** +** a +** --- +** | | +** f| |b +** | g | +** --- +** | | +** e| |c +** | | +** --- +** d +*/ + +struct Seg7disp { + unsigned seg_a : 1; + unsigned seg_b : 1; + unsigned seg_c : 1; + unsigned seg_d : 1; + unsigned seg_e : 1; + unsigned seg_f : 1; + unsigned seg_g : 1; +} Seg7digits[10] = { + { 1, 1, 1, 1, 1, 1, 0 }, /* 0 */ + { 0, 1, 1, 0, 0, 0, 0 }, /* 1 */ + { 1, 1, 0, 1, 1, 0, 1 }, /* 2 */ + { 1, 1, 1, 1, 0, 0, 1 }, /* 3 */ + { 0, 1, 1, 0, 0, 1, 1 }, /* 4 */ + { 1, 0, 1, 1, 0, 1, 1 }, /* 5 */ + { 1, 0, 1, 1, 1, 1, 1 }, /* 6 */ + { 1, 1, 1, 0, 0, 0, 0 }, /* 7 */ + { 1, 1, 1, 1, 1, 1, 1 }, /* 8 */ + { 1, 1, 1, 1, 0, 1, 1 } /* 9 */ +}; + +char *str27seg(char *string) +{ + char *str; + int ch; + + for (str = string ; *str; ++str) + { + if (!isdigit(*str)) + return NULL; + ch = CAST(int, Seg7digits[*str - '0']); + *str = (char)(ch & 0xff); + } + return string; +} + +#ifdef TEST + +main() +{ + char tstrng[] = "0123456789", *segs; + + printf("str27seg() returned %p", segs = str27seg(tstrng)); + if (segs) + { + char *ptr; + struct Seg7disp ch; + int i; + + puts(" & produced:\n"); + for (ptr = segs ; *ptr; ++ptr) + { + ch = CAST(struct Seg7disp, *ptr); + if (ch.seg_a) + DISP(" --- "); + else DISP(" "); + DISP(" "); + } + puts(""); + for (i = 0; i < 3; ++i) + { + for (ptr = segs ; *ptr; ++ptr) + { + ch = CAST(struct Seg7disp, *ptr); + if (ch.seg_f) + DISP("| "); + else DISP(" "); + if (ch.seg_b) + DISP("|"); + else DISP(" "); + DISP(" "); + } + puts(""); + } + for (ptr = segs ; *ptr; ++ptr) + { + ch = CAST(struct Seg7disp, *ptr); + if (ch.seg_g) + DISP(" --- "); + else DISP(" "); + DISP(" "); + } + puts(""); + for (i = 0; i < 3; ++i) + { + for (ptr = segs ; *ptr; ++ptr) + { + ch = CAST(struct Seg7disp, *ptr); + if (ch.seg_e) + DISP("| "); + else DISP(" "); + if (ch.seg_c) + DISP("|"); + else DISP(" "); + DISP(" "); + } + puts(""); + } + for (ptr = segs ; *ptr; ++ptr) + { + ch = CAST(struct Seg7disp, *ptr); + if (ch.seg_d) + DISP(" --- "); + else DISP(" "); + DISP(" "); + } + puts(""); + } + else puts("\n"); + + return 0; +} + +#endif diff --git a/reference/C/CONTRIB/SNIP/strat.c b/reference/C/CONTRIB/SNIP/strat.c new file mode 100755 index 0000000..fb00d5b --- /dev/null +++ b/reference/C/CONTRIB/SNIP/strat.c @@ -0,0 +1,170 @@ +/* +** strat.c 10-5-91 Robert Mashlan, public domain +** +** Interface functions to DOS 3.0+ set allocation strategy +** and get allocation strategy functions via int 21h, +** function 58h. +** +** By setting the dos allocation strategy to LAST_FIT_LOW +** before using DOS the set handle count function int 21h, +** function 67h, DOS will allocate memory for the extended +** file handle table at the end of free memory instead of +** after the last heap allocation, with the benefit of +** allowing the heap manager make further contiguous +** allocations from the operating system. +** +*/ + +#include <stdlib.h> +#include <dos.h> +#include "strat.h" + +/* +** Gets dos memory allocation strategy via function 0x58. +** Returns allocation strategy, else returns -1 and sets +** _doserrno on error. +*/ + +int get_alloc_strat(void) +{ + union REGS r; + + r.x.ax = 0x5800; /* DOS "get allocation strategy" */ + int86(0x21,&r,&r); + if (r.x.cflag) /* error? */ + { + _doserrno = r.x.ax; /* save error code */ + return -1; + } + else return r.x.ax; +} + +/* +** Sets DOS memory allocation strategy +** returns allocation strategy on success, +** else returns -1 and sets _doserrno on error +*/ + +int set_alloc_strat( int strat ) +{ + union REGS r; + + r.x.ax = 0x5801; /* DOS "set allocation strategy" */ + r.x.bx = strat; + int86(0x21,&r,&r); + if (r.x.cflag) /* error? */ + { + _doserrno = r.x.ax; /* save error code */ + return -1; + } + _doserrno = 0; + return strat; +} + +/* +** Uses dos function 67h to increase open file handle count. +** Returns -1 and sets _doserrno on error, 0 otherwise. +*/ + +int set_handle_count( unsigned nhandles ) +{ + union REGS r; + + r.x.ax = 0x6700; + r.x.bx = nhandles; + int86(0x21,&r,&r); + if(r.x.cflag) + { + _doserrno = r.x.ax; + return -1; + } + _doserrno = 0; + return 0; +} + +#ifdef DEMO + +#include <stdio.h> +#include <stdlib.h> +#include <io.h> +#include <fcntl.h> + +/* +** returns maximum number of files that can be open +*/ + +int handle_count(void) +{ + int handles[500]; + int i, result; + + /* try allocating as many file handles as possible */ + + for (i = 0; i < 500; i++) + { + if( (handles[i]=open("NUL",O_WRONLY)) == -1 ) + break; + } + result = i; + + /* close all files opened */ + + for (i--; i >= 0; i--) + close(handles[i]); + return result; +} + + +/* +** Memory test, returns number of kilobytes that +** can be allocated before failure. +*/ + +int memtest(void) +{ + static void *mem[1024]; + int i,result; + + /* try allocating as many 1K blocks as possible */ + + for(i=0;i<1024;i++) + { + if( (mem[i]=malloc(1024)) == NULL ) + break; + } + result = i; /* save result */ + + /* free memory allocated */ + + for(i--; i >= 0; i--) + free(mem[i]); + return result; +} + +#define checkdoserror(f) \ + ((f==-1)?printf("%s failed, doserror = %#02x\n",#f,_doserrno):(void)0) + +int main(void) +{ + int strat; + + /* do pre-test diagnostics */ + + printf("allocated %d Kbytes before failure\n",memtest()); + printf("opened %d files\n",handle_count()); + + strat = get_alloc_strat(); /* save current allocation strategy */ + checkdoserror(set_alloc_strat(LAST_FIT_LOW)); + puts("setting handle count to 50, with changed allocation strategy"); + checkdoserror(set_handle_count(50)); + checkdoserror(set_alloc_strat(strat)); /* restore strategy */ + + /* do post-test diagnostics */ + + printf("allocated %d Kbytes before failure\n",memtest()); + printf("opened %d files\n",handle_count()); + + return 0; +} + +#endif diff --git a/reference/C/CONTRIB/SNIP/strat.h b/reference/C/CONTRIB/SNIP/strat.h new file mode 100755 index 0000000..1dbb2e6 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/strat.h @@ -0,0 +1,22 @@ +/* +** strat.h 10-5-91 Robert Mashlan, public domain +** +** header file for strat.c +** +*/ + +const enum { + FIRST_FIT_LOW, + BEST_FIT_LOW, + LAST_FIT_LOW, + FIRST_FIT_HIGH = 0x80, /* these strategies available only in DOS 5.0 */ + BEST_FIT_HIGH, + LAST_FIT_HIGH, + FIRST_FIT_HIGHONLY = 0x40, + BEST_FIT_HIGHONLY, + LAST_FIT_HIGHONLY + }; + +int get_alloc_strat(void); +int set_alloc_strat( int strat ); +int set_handle_count( unsigned nhandles ); diff --git a/reference/C/CONTRIB/SNIP/strdup.c b/reference/C/CONTRIB/SNIP/strdup.c new file mode 100755 index 0000000..88a2b3e --- /dev/null +++ b/reference/C/CONTRIB/SNIP/strdup.c @@ -0,0 +1,15 @@ +/* +** Portable, public domain strdup() by Bob Stout +*/ + +#include <stdlib.h> +#include <string.h> + +char *strdup(const char *string) +{ + char *new; + + if (NULL != (new = malloc(strlen(string) + 1))) + strcpy(new, string); + return new; +} diff --git a/reference/C/CONTRIB/SNIP/strecpy.asm b/reference/C/CONTRIB/SNIP/strecpy.asm new file mode 100755 index 0000000..223dad4 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/strecpy.asm @@ -0,0 +1,92 @@ + page ,132 + title STRECPY +COMMENT $ + Author: Leslie Satenstein + A form of strcpy() where the result returned is the + nul terminating character of the first argument. In many cases + this function is move efficient than the equivalent + strcpy, followed by strcat. + + The assembler code does a strlen followed by a memcpy, + and makes use of the special string move instructions + intrinsic to the intel 8088, 80186, 80286, '386 and '486s. + + Use as: strecpy(strecpy(target,"first part"),"Second part"); + in place of + strcat(strcpy(target,"first part"),"Second part"); + + One of the ways the C code appears is: + char *strecpy(char *target,const char *src) + { + return target+strlen(strcpy(target,src)); + } + Another way is to do your own looping: + + char *strecpy(char *target,const char *src) + { + char *cpt,*cps; /* many compilers optimise better + * when local pointers are declared + * (locals can be assigned registers) + */ + cpt=target-1; + cps=src-1; + do + { + *++cpt = *++src; /* copy first, ask questions later */ + } while(*cpt!='\0'); + return cpt; + } + + $ + +; Requires MASM 5.1 or later or equivalent +; +; Assemble with: MASM /Mx /z ... +; TASM /jMASM /mx /z ... + +% .MODEL memodel,C ;Add model support via command + ;line macros, e.g. + ;MASM /Dmemodel=LARGE, + ;MASM /Dmemodel=SMALL, etc. + PUBLIC STRECPY + + .DATA + .CODE +if @DataSize +strecpy proc uses si di ds,target:FAR ptr byte,src:FAR ptr byte + les di,src ; load es:di with src + mov si,di ; put copy to bx:si + mov bx,es +else +strecpy proc uses si di,target:NEAR ptr byte,src:NEAR ptr byte + mov di,ds ; make es same as ds + mov es,di + mov di,src + mov si,di ; put copy to es:si +endif + xor ax,ax ; scan for the nul at end of string + mov cx,-1 + repne scasb + not cx ; cx = strlen(src)+1 ; +if @Datasize + les di,target ; this is where copy is to begin + mov dx,es ; dx has segment, di has offset to target + mov ds,bx ; ds:si have pointer to src +else + mov di,target ; this is where copy is to begin +endif + test di,1 ; if we are on odd address, do one byte move + jz on_even + movsb ; now, prepare to move words at a + dec cx ;time to target +on_even: + shr cx,1 ; carry flag has remainder after divide by 2 + rep movsw ; move this many words + jnc fini ; if no carry, we are finished + movsb +fini: + xchg di,ax ; set up return value, dx has seg value + dec ax ; backup to the nul character + ret +strecpy endp + end diff --git a/reference/C/CONTRIB/SNIP/strftime.c b/reference/C/CONTRIB/SNIP/strftime.c new file mode 100755 index 0000000..f6fae24 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/strftime.c @@ -0,0 +1,339 @@ +/** + * + * strftime.c + * + * implements the ansi c function strftime() + * + * written 6 september 1989 by jim nutt + * released into the public domain by jim nutt + * + * modified 21-Oct-89 by Rob Duff + * +**/ + +#include <stddef.h> /* for size_t */ +#include <stdarg.h> /* for va_arg */ +#include <time.h> /* for struct tm */ + +/* +** The following line should be appended to TIME.H. +** Also copy size_t define from STRING.H. +*/ + +size_t strftime(char *s, size_t maxs, const char *f, const struct tm *t); + +static char *aday[] = { + "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" +}; + +static char *day[] = { + "Sunday", "Monday", "Tuesday", "Wednesday", + "Thursday", "Friday", "Saturday" +}; + +static char *amonth[] = { + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" +}; + +static char *month[] = { + "January", "February", "March", "April", "May", "June", + "July", "August", "September", "October", "November", "December" +}; + +extern char *tzname[2]; +static char buf[26]; + +static void strfmt(char *str, const char *fmt, ...); + +/** + * + * size_t strftime(char *str, + * size_t maxs, + * const char *fmt, + * const struct tm *t) + * + * this functions acts much like a sprintf for time/date output. + * given a pointer to an output buffer, a format string and a + * time, it copies the time to the output buffer formatted in + * accordance with the format string. the parameters are used + * as follows: + * + * str is a pointer to the output buffer, there should + * be at least maxs characters available at the address + * pointed to by str. + * + * maxs is the maximum number of characters to be copied + * into the output buffer, included the '\0' terminator + * + * fmt is the format string. a percent sign (%) is used + * to indicate that the following character is a special + * format character. the following are valid format + * characters: + * + * %A full weekday name (Monday) + * %a abbreviated weekday name (Mon) + * %B full month name (January) + * %b abbreviated month name (Jan) + * %c standard date and time representation + * %d day-of-month (01-31) + * %H hour (24 hour clock) (00-23) + * %I hour (12 hour clock) (01-12) + * %j day-of-year (001-366) + * %M minute (00-59) + * %m month (01-12) + * %p local equivalent of AM or PM + * %S second (00-59) + * %U week-of-year, first day sunday (00-53) + * %W week-of-year, first day monday (00-53) + * %w weekday (0-6, sunday is 0) + * %X standard time representation + * %x standard date representation + * %Y year with century + * %y year without century (00-99) + * %Z timezone name + * %% percent sign + * + * the standard date string is equivalent to: + * + * %a %b %d %Y + * + * the standard time string is equivalent to: + * + * %H:%M:%S + * + * the standard date and time string is equivalent to: + * + * %a %b %d %H:%M:%S %Y + * + * strftime returns the number of characters placed in the + * buffer, not including the terminating \0, or zero if more + * than maxs characters were produced. + * +**/ + +size_t strftime(char *s, size_t maxs, const char *f, const struct tm *t) +{ + int w; + char *p, *q, *r; + + p = s; + q = s + maxs - 1; + while ((*f != '\0')) + { + if (*f++ == '%') + { + r = buf; + switch (*f++) + { + case '%' : + r = "%"; + break; + + case 'a' : + r = aday[t->tm_wday]; + break; + + case 'A' : + r = day[t->tm_wday]; + break; + + case 'b' : + r = amonth[t->tm_mon]; + break; + + case 'B' : + r = month[t->tm_mon]; + break; + + case 'c' : + strfmt(r, "%0 %0 %2 %2:%2:%2 %4", + aday[t->tm_wday], amonth[t->tm_mon], + t->tm_mday,t->tm_hour, t->tm_min, + t->tm_sec, t->tm_year+1900); + break; + + case 'd' : + strfmt(r,"%2",t->tm_mday); + break; + + case 'H' : + strfmt(r,"%2",t->tm_hour); + break; + + case 'I' : + strfmt(r,"%2",(t->tm_hour%12)?t->tm_hour%12:12); + break; + + case 'j' : + strfmt(r,"%3",t->tm_yday+1); + break; + + case 'm' : + strfmt(r,"%2",t->tm_mon+1); + break; + + case 'M' : + strfmt(r,"%2",t->tm_min); + break; + + case 'p' : + r = (t->tm_hour>11)?"PM":"AM"; + break; + + case 'S' : + strfmt(r,"%2",t->tm_sec); + break; + + case 'U' : + w = t->tm_yday/7; + if (t->tm_yday%7 > t->tm_wday) + w++; + strfmt(r, "%2", w); + break; + + case 'W' : + w = t->tm_yday/7; + if (t->tm_yday%7 > (t->tm_wday+6)%7) + w++; + strfmt(r, "%2", w); + break; + + case 'w' : + strfmt(r,"%1",t->tm_wday); + break; + + case 'x' : + strfmt(r, "%3s %3s %2 %4", aday[t->tm_wday], + amonth[t->tm_mon], t->tm_mday, t->tm_year+1900); + break; + + case 'X' : + strfmt(r, "%2:%2:%2", t->tm_hour, + t->tm_min, t->tm_sec); + break; + + case 'y' : + strfmt(r,"%2",t->tm_year%100); + break; + + case 'Y' : + strfmt(r,"%4",t->tm_year+1900); + break; + + case 'Z' : + r = (t->tm_isdst && tzname[1][0])?tzname[1]:tzname[0]; + break; + + default: + buf[0] = '%'; /* reconstruct the format */ + buf[1] = f[-1]; + buf[2] = '\0'; + if (buf[1] == 0) + f--; /* back up if at end of string */ + } + while (*r) + { + if (p == q) + { + *q = '\0'; + return 0; + } + *p++ = *r++; + } + } + else + { + if (p == q) + { + *q = '\0'; + return 0; + } + *p++ = f[-1]; + } + } + *p = '\0'; + return p - s; +} + +/* + * stdarg.h + * +typedef void *va_list; +#define va_start(vp,v) (vp=((char*)&v)+sizeof(v)) +#define va_arg(vp,t) (*((t*)(vp))++) +#define va_end(vp) + * + */ + +static int pow[5] = { 1, 10, 100, 1000, 10000 }; + +/** + * static void strfmt(char *str, char *fmt); + * + * simple sprintf for strftime + * + * each format descriptor is of the form %n + * where n goes from zero to four + * + * 0 -- string %s + * 1..4 -- int %?.?d + * +**/ + +static void strfmt(char *str, const char *fmt, ...) +{ + int ival, ilen; + char *sval; + va_list vp; + + va_start(vp, fmt); + while (*fmt) + { + if (*fmt++ == '%') + { + ilen = *fmt++ - '0'; + if (ilen == 0) /* zero means string arg */ + { + sval = va_arg(vp, char*); + while (*sval) + *str++ = *sval++; + } + else /* always leading zeros */ + { + ival = va_arg(vp, int); + while (ilen) + { + ival %= pow[ilen--]; + *str++ = (char)('0' + ival / pow[ilen]); + } + } + } + else *str++ = fmt[-1]; + } + *str = '\0'; + va_end(vp); +} + +#ifdef TEST + +#include <stdio.h> /* for printf */ +#include <time.h> /* for strftime */ + +char test[80]; + +int main(int argc, char *argv[]) +{ + int len; + char *fmt; + time_t now; + + time(&now); + + fmt = (argc == 1) ? "%I:%M %p\n%c\n" : argv[1]; + len = strftime(test,sizeof test, fmt, localtime(&now)); + printf("%d: %s\n", len, test); + return !len; +} + +#endif /* TEST */ diff --git a/reference/C/CONTRIB/SNIP/stripeof.c b/reference/C/CONTRIB/SNIP/stripeof.c new file mode 100755 index 0000000..f2a17ac --- /dev/null +++ b/reference/C/CONTRIB/SNIP/stripeof.c @@ -0,0 +1,61 @@ +/* +** STRIPEOF.C +** +** public domain demo by Bob Stout +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <io.h> +#include <fcntl.h> + +#define BUFSIZE 16384 + +int main(int argc, char *argv[]) +{ + char *buf; + + if (2 > argc) + { + puts("Usage: STRIPEOF filename1 [...filenameN]"); + return EXIT_FAILURE; + } + if (NULL == (buf = malloc(BUFSIZE))) + { + puts("STRIPEOF internal failure"); + return EXIT_FAILURE; + } + while (--argc) + { + int fd; + size_t bytes; + int found = 0; + long zpos = 0L; + + if (-1 == (fd = open(*(++argv), O_RDWR | O_BINARY))) + { + printf("Couldn't open %s\n", *argv); + return EXIT_FAILURE; + } + while (0 < (bytes = read(fd, buf, BUFSIZE))) + { + int i; + + for (i = 0; i < (int)bytes; ++i) + { + if (('Z' - 64) == buf[i]) + { + found = 1; + zpos += i; + break; + } + } + if (found) + break; + zpos += bytes; + } + if (found) + chsize(fd, zpos); + } + return EXIT_SUCCESS; +} diff --git a/reference/C/CONTRIB/SNIP/strrepl.c b/reference/C/CONTRIB/SNIP/strrepl.c new file mode 100755 index 0000000..bca07c4 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/strrepl.c @@ -0,0 +1,74 @@ +/* + -------------------------------------------------------------------- + Module: REPLACE.C + Author: Gilles Kohl + Started: 09.06.1992 12:16:47 + Modified: 09.06.1992 12:41:41 + Subject: Replace one string by another in a given buffer. + This code is public domain. Use freely. + -------------------------------------------------------------------- +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +/* + * StrReplace: Replace OldStr by NewStr in string Str. + * + * Str should have enough allocated space for the replacement, no check + * is made for this. Str and OldStr/NewStr should not overlap. + * The empty string ("") is found at the beginning of every string. + * + * Returns: pointer to first location behind where NewStr was inserted + * or NULL if OldStr was not found. + * This is useful for multiple replacements, see example in main() below + * (be careful not to replace the empty string this way !) + */ + +char *StrReplace(char *Str, char *OldStr, char *NewStr) +{ + int OldLen, NewLen; + char *p, *q; + + if(NULL == (p = strstr(Str, OldStr))) + return p; + OldLen = strlen(OldStr); + NewLen = strlen(NewStr); + memmove(q = p+NewLen, p+OldLen, strlen(p+OldLen)+1); + memcpy(p, NewStr, NewLen); + return q; +} + +#ifdef TEST + +/* + * Test main(). + * Given two arguments, replaces the first arg. in the lines read from + * stdin by the second one. + * Example invocation: + * replace printf puts <replace.c + * will replace all printf's by puts in replace's source. + * + */ + +int main(int argc, char *argv[]) +{ + char buf[200]; + char *Start; + + if(argc != 3) + exit(1); + + /* Repeat until all occurences replaced */ + + while(NULL != (Start = gets(buf))) + { + while(NULL != (Start = StrReplace(Start, argv[1], argv[2]))) + ; + printf("%s\n", buf); + } + return 0; +} + +#endif TEST diff --git a/reference/C/CONTRIB/SNIP/strrev.c b/reference/C/CONTRIB/SNIP/strrev.c new file mode 100755 index 0000000..20d9952 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/strrev.c @@ -0,0 +1,37 @@ +/* +** STRREV.C - reverse a string in place +** +** public domain by Bob Stout +*/ + +#include <string.h> + +char *strrev(char *str) +{ + char *p1, *p2; + + if (! str || ! *str) + return str; + for (p1 = str, p2 = str + strlen(str) - 1; p2 > p1; ++p1, --p2) + { + *p1 ^= *p2; + *p2 ^= *p1; + *p1 ^= *p2; + } + return str; +} + +#ifdef TEST + +#include <stdio.h> + +int main(int argc, char *argv[]) +{ + while (--argc) + { + printf("\"%s\" backwards is ", *++argv); + printf("\"%s\"\n", strrev(*argv)); + } +} + +#endif /* TEST */ diff --git a/reference/C/CONTRIB/SNIP/strsort.c b/reference/C/CONTRIB/SNIP/strsort.c new file mode 100755 index 0000000..ed083d1 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/strsort.c @@ -0,0 +1,34 @@ +/* +** strsort() -- Shell sort an array of string pointers via strcmp() +** public domain by Ray Gardner Denver, CO 12/88 +*/ + +#include <string.h> +#include <stddef.h> + +void strsort (char **array, size_t array_size) +{ + size_t gap, i, j; + char **a, **b, *tmp; + + for (gap = 0; ++gap < array_size; ) + gap *= 2; + while (gap /= 2) + { + for (i = gap; i < array_size; i++) + { + for (j = i - gap; ;j -= gap) + { + a = array + j; + b = a + gap; + if (strcmp(*a, *b) <= 0) + break; + tmp = *a; + *a = *b; + *b = tmp; + if (j < gap) + break; + } + } + } +} diff --git a/reference/C/CONTRIB/SNIP/strucfil.c b/reference/C/CONTRIB/SNIP/strucfil.c new file mode 100755 index 0000000..a0b6522 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/strucfil.c @@ -0,0 +1,190 @@ +/******************************************************************* + * Generic structure <> disk file manipulations. These functions + * form a basic template for reading and writing structures to a + * sequential file. This template is probably most useful for files + * with 500 or less records and eliminates the need for a more + * elaborate file handler such as C-Tree, DB-Vista, Mix etc. + * Routines to put data in the struct is out of scope here. + * Written by Lynn Nash 8/28/91 and donated to the public domain. + */ +#include <io.h> +#include <string.h> +#include <stdlib.h> +#include <stdio.h> + +#ifndef ERROR +#define ERROR -1 +#define OK 0 +#endif + +#ifndef TRUE +#define TRUE 1 +#define FALSE !TRUE +#endif + +/* make sure the record structure is byte aligned */ + +#if defined(__TURBOC__) + #pragma option -a- +#elif defined(__ZTC__) + #pragma ZTC align 1 +#else /* MSC/QC/WATCOM/METAWARE */ + #pragma pack(1) +#endif + +static struct blackbook { + int delete_flag; /* 0 = active -1 = deleted */ + int recordnum; /* a sequential number in the file */ + /* The data fields in asciiz. */ + char firstname[11]; + char lastname[16]; + char addr[26]; + char city[16]; + char state[3]; + char zip[10]; + char phone[11]; +} rec, oldrec; /* 97 byte record * 2 */ + +#pragma pack() + +/*-------------------- general globals ---------------------*/ + +static long cur_rec = 0; /* the current record number */ +static FILE *fsptr = NULL; /* fixed record data file pointer */ + +/* if file exists open in read/write mode else create file */ + +FILE * open_file(char *filename) +{ + if (access(filename, 0) == 0) + fsptr = fopen(filename, "rb+"); + else fsptr = fopen(filename, "wb+"); + return fsptr; /* return the file pointer */ +} + +/* add new records to the data file */ + +int datadd(void) +{ + if (fsptr) + { + if (fseek(fsptr, 0L, SEEK_END) != 0) + return ERROR; /* seek failure */ + rec.delete_flag = 0; /* active record tag */ + rec.recordnum = (int) (ftell(fsptr) / + (long) sizeof(struct blackbook)); + if (fwrite(&rec, sizeof(struct blackbook), 1, fsptr) != 1) + { + return ERROR; /* write error */ + } + else + { + /* put your clean up code here */ + return OK; + } + } + return ERROR; +} + +/* tag the last record read in the file as deleted */ + +int data_delete(void) +{ + if (fsptr) + { + if (fseek(fsptr, (long) sizeof(struct blackbook) * -1L, + SEEK_CUR) != 0) + { + return ERROR; + } + rec.delete_flag = -1; /* tag the record as deleted */ + if (fwrite(&rec, sizeof(struct blackbook), 1, fsptr) != 1) + return ERROR; + else return OK; + } + return ERROR; +} + +/* read a random structure. If successful the global cur_rec will + * contain the number of the last record read & it can be compared + * to the number in the struct as a double check (belt & suspenders) + */ + +int data_read(long recnum) +{ + if (fseek(fsptr, (long) sizeof(struct blackbook) * recnum, + SEEK_SET) != 0) + { + return ERROR; + } + cur_rec = recnum; /* keep tabs on record pointer in global */ + + /* now read the record into save struct*/ + + if (fread(&oldrec, sizeof(struct blackbook), 1, fsptr) != 1) + { + return ERROR; + } + else /* copy save struct to edit struct */ + { + memcpy(&rec, &oldrec, sizeof(struct blackbook)); + return OK; + } +} + +/* rewrite the last read record back to disk */ + +int data_update(void) +{ + if (memcmp(&rec, &oldrec, sizeof(struct blackbook)) == 0) + return TRUE; /* no update needed */ + + /* back up one record before writing */ + + if (fseek(fsptr, (long) sizeof(struct blackbook) * -1L, + SEEK_CUR) != 0) + { + return ERROR; /* seek error */ + } + + /* now write the record */ + + if (fwrite(&rec, sizeof(struct blackbook), 1, fsptr) != 1) + return ERROR; /* write error */ + return OK; +} + +/* get the next valid record in the file */ + +int read_forward(void) +{ + do + { + cur_rec++; /* upcount the record number */ + if (data_read(cur_rec) != 0) + { + cur_rec--; /* decrement the record number */ + return ERROR; + } + } while (oldrec.delete_flag != 0); /* record read was deleted */ + return OK; +} + +/* get the previous valid record in the file */ + +int read_backward(void) +{ + do + { + cur_rec--; /* decrement the record number */ + if (cur_rec >= 0) + { + if ( data_read(cur_rec) != 0 ) + { + cur_rec++; /* increment the record number */ + return ERROR; + } + } + } while (oldrec.delete_flag != 0); /* record read was deleted */ + return OK; +} diff --git a/reference/C/CONTRIB/SNIP/strupr.c b/reference/C/CONTRIB/SNIP/strupr.c new file mode 100755 index 0000000..a4bca57 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/strupr.c @@ -0,0 +1,29 @@ +/* +** Portable, public domain strupr() & strlwr() +*/ + +#include <ctype.h> + +char *strupr(char *str) +{ + char *string = str; + + if (str) + { + for ( ; *str; ++str) + *str = toupper(*str); + } + return string; +} + +char *strlwr(char *str) +{ + char *string = str; + + if (str) + { + for ( ; *str; ++str) + *str = tolower(*str); + } + return string; +} diff --git a/reference/C/CONTRIB/SNIP/stub.c b/reference/C/CONTRIB/SNIP/stub.c new file mode 100755 index 0000000..dd8f9a5 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/stub.c @@ -0,0 +1,115 @@ +/* +** STUB.C - Utility to truncate files +** +** STUB is used with MAKE utilities which lack the ability to timestamp +** library object modules to reduce disk space requirements. After +** compiling and building your library or executable, run "STUB *.OBJ" +** to truncate all object files to zero length. The files' time and +** date stamps will remain unchanged. By doing this, your make utility +** will still know which modules are out of date even though the files +** themselves have all been truncated to zero length. STUB also supports +** the standard response file format so you can use your linker response +** files to direct the files to be truncated. +** +** public domain by Bob Stout +** +** Notes: To expand command line arguments with wildcards, +** TC/TC++/BC++ - Link in WILDARGS.OBJ. +** MSC/QC - Link in SETARGV.OBJ. +** ZTC/C++ - Link in _MAINx.OBJ, where 'x' is the memory model. +** Watcom C/C++ - Compile & link with WILDARGV.C +** +** Allows file list(s) using standard "@file_list_name" convention. +*/ + +#include <stdio.h> +#include <string.h> +#include <dos.h> +#include <io.h> +#include <fcntl.h> + +#define LAST_CHAR(s) (s)[strlen(s)-1] + +int fd; + +void truncate(char *); + +int main(int argc, char **argv) +{ + int i; + + if (2 > argc) + { + puts("Usage: STUB filespec [...filespec]"); + puts("where: filespec = fully-specified file name, or"); + puts(" filespec = wildcard-specified file name, or"); + puts(" filespec = response file name, e.g. \"@FILE.LST\""); + return 1; + } + + for (i = 1; i < argc; ++i) /* Scan for simple file specs */ + { + if ('@' == *argv[i]) + continue; + else truncate(argv[i]); + } + for (i = 1; i < argc; ++i) /* Scan for response file specs */ + { + if ('@' == *argv[i]) + { + FILE *fp; + char buf[256], *ptr = &argv[i][1]; + + if (NULL == (fp = fopen(ptr, "r"))) + { + printf("\aSTUB: Error opening %s\n", ptr); + return -1; + } + while (NULL != fgets(buf, 255, fp)) + { + LAST_CHAR(buf) = '\0'; /* Strip '\n' */ + truncate(buf); + } + fclose(fp); + } + } + return 0; +} + +/* +** The actual truncation function +*/ + +#ifdef __ZTC__ + #define GETFTIME dos_getftime + #define SETFTIME dos_setftime +#else + #define GETFTIME _dos_getftime + #define SETFTIME _dos_setftime +#endif + +void truncate(char *fname) +{ +#ifdef __TURBOC__ + struct ftime Ftime; +#else + unsigned short date, time; +#endif + + fd = open(fname, O_WRONLY); + +#ifdef __TURBOC__ /* Save the time/date */ + getftime(fd, &Ftime); +#else + GETFTIME(fd, &date, &time); +#endif + + chsize(fd, 0L); /* Truncate the file */ + +#ifdef __TURBOC__ /* Restore the time/date */ + setftime(fd, &Ftime); +#else + SETFTIME(fd, date, time); +#endif + close(fd); +} diff --git a/reference/C/CONTRIB/SNIP/style.c b/reference/C/CONTRIB/SNIP/style.c new file mode 100755 index 0000000..d25c111 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/style.c @@ -0,0 +1,32 @@ +/***************************************************************************/ +/* Global (public) headers look like this */ +/* */ +/* foo() */ +/* Parameters: description of each passed datum */ +/* Returns: description of return value & significance */ +/* Side effects: complete details */ +/* Notes: extra info */ +/***************************************************************************/ + +/* +** Static (local) headers look like this +** +** Brief description +*/ + +int foo(void) /* use ANSI prototypes on every compiler that supports 'em */ +{ + int local1, local2; /* local variable declarations are always + followed by a blank line */ + + do_stuff(); + if (bar(local1)) + { /* long comments here *//* this lines up with -----------+ */ + char *local3; /* autos declared close to use | */ + /* | */ + do_more_stuff(); /* (everything else indented) | */ + local2 = strlen(local3);/* | */ + } /* this <------------------------+ */ + else local2 = fubar(); /* using tab >= 6, else's line up */ + return local2; +} /* no question where functions end! */ diff --git a/reference/C/CONTRIB/SNIP/sunriset.c b/reference/C/CONTRIB/SNIP/sunriset.c new file mode 100755 index 0000000..fa67e67 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/sunriset.c @@ -0,0 +1,507 @@ +/* + +SUNRISET.C - computes Sun rise/set times, start/end of twilight, and + the length of the day at any date and latitude + +Written as DAYLEN.C, 1989-08-16 + +Modified to SUNRISET.C, 1992-12-01 + +(c) Paul Schlyter, 1989, 1992 + +Released to the public domain by Paul Schlyter, December 1992 + +*/ + + +#include <stdio.h> +#include <math.h> + + +/* A macro to compute the number of days elapsed since 2000 Jan 0.0 */ +/* (which is equal to 1999 Dec 31, 0h UT) */ + +#define days_since_2000_Jan_0(y,m,d) \ + (367L*(y)-((7*((y)+(((m)+9)/12)))/4)+((275*(m))/9)+(d)-730530L) + +/* Some conversion factors between radians and degrees */ + +#ifndef PI + #define PI 3.1415926535897932384 +#endif + +#define RADEG ( 180.0 / PI ) +#define DEGRAD ( PI / 180.0 ) + +/* The trigonometric functions in degrees */ + +#define sind(x) sin((x)*DEGRAD) +#define cosd(x) cos((x)*DEGRAD) +#define tand(x) tan((x)*DEGRAD) + +#define atand(x) (RADEG*atan(x)) +#define asind(x) (RADEG*asin(x)) +#define acosd(x) (RADEG*acos(x)) +#define atan2d(y,x) (RADEG*atan2(y,x)) + + +/* Following are some macros around the "workhorse" function __daylen__ */ +/* They mainly fill in the desired values for the reference altitude */ +/* below the horizon, and also selects whether this altitude should */ +/* refer to the Sun's center or its upper limb. */ + + +/* This macro computes the length of the day, from sunrise to sunset. */ +/* Sunrise/set is considered to occur when the Sun's upper limb is */ +/* 35 arc minutes below the horizon (this accounts for the refraction */ +/* of the Earth's atmosphere). */ +#define day_length(year,month,day,lon,lat) \ + __daylen__( year, month, day, lon, lat, -35.0/60.0, 1 ) + +/* This macro computes the length of the day, including civil twilight. */ +/* Civil twilight starts/ends when the Sun's center is 6 degrees below */ +/* the horizon. */ +#define day_civil_twilight_length(year,month,day,lon,lat) \ + __daylen__( year, month, day, lon, lat, -6.0, 0 ) + +/* This macro computes the length of the day, incl. nautical twilight. */ +/* Nautical twilight starts/ends when the Sun's center is 12 degrees */ +/* below the horizon. */ +#define day_nautical_twilight_length(year,month,day,lon,lat) \ + __daylen__( year, month, day, lon, lat, -12.0, 0 ) + +/* This macro computes the length of the day, incl. astronomical twilight. */ +/* Astronomical twilight starts/ends when the Sun's center is 18 degrees */ +/* below the horizon. */ +#define day_astronomical_twilight_length(year,month,day,lon,lat) \ + __daylen__( year, month, day, lon, lat, -18.0, 0 ) + + +/* This macro computes times for sunrise/sunset. */ +/* Sunrise/set is considered to occur when the Sun's upper limb is */ +/* 35 arc minutes below the horizon (this accounts for the refraction */ +/* of the Earth's atmosphere). */ +#define sun_rise_set(year,month,day,lon,lat,rise,set) \ + __sunriset__( year, month, day, lon, lat, -35.0/60.0, 1, rise, set ) + +/* This macro computes the start and end times of civil twilight. */ +/* Civil twilight starts/ends when the Sun's center is 6 degrees below */ +/* the horizon. */ +#define civil_twilight(year,month,day,lon,lat,start,end) \ + __sunriset__( year, month, day, lon, lat, -6.0, 0, start, end ) + +/* This macro computes the start and end times of nautical twilight. */ +/* Nautical twilight starts/ends when the Sun's center is 12 degrees */ +/* below the horizon. */ +#define nautical_twilight(year,month,day,lon,lat,start,end) \ + __sunriset__( year, month, day, lon, lat, -12.0, 0, start, end ) + +/* This macro computes the start and end times of astronomical twilight. */ +/* Astronomical twilight starts/ends when the Sun's center is 18 degrees */ +/* below the horizon. */ +#define astronomical_twilight(year,month,day,lon,lat,start,end) \ + __sunriset__( year, month, day, lon, lat, -18.0, 0, start, end ) + + +/* Function prototypes */ + +double __daylen__( int year, int month, int day, double lon, double lat, + double altit, int upper_limb ); + +int __sunriset__( int year, int month, int day, double lon, double lat, + double altit, int upper_limb, double *rise, double *set ); + +void sunpos( double d, double *lon, double *r ); + +void sun_RA_dec( double d, double *RA, double *dec, double *r ); + +double revolution( double x ); + +double rev180( double x ); + +double GMST0( double d ); + + + +/* A small test program */ + +void main(void) +{ + int year,month,day; + double lon, lat; + double daylen, civlen, nautlen, astrlen; + double rise, set, civ_start, civ_end, naut_start, naut_end, + astr_start, astr_end; + int rs, civ, naut, astr; + + printf( "Longitude (+ is east) and latitude (+ is north) : " ); + scanf( "%lf %lf", &lon, &lat ); + + for(;;) + { + printf( "Input date ( yyyy mm dd ) (ctrl-C exits): " ); + scanf( "%d %d %d", &year, &month, &day ); + + daylen = day_length(year,month,day,lon,lat); + civlen = day_civil_twilight_length(year,month,day,lon,lat); + nautlen = day_nautical_twilight_length(year,month,day,lon,lat); + astrlen = day_astronomical_twilight_length(year,month,day, + lon,lat); + + printf( "Day length: %5.2f hours\n", daylen ); + printf( "With civil twilight %5.2f hours\n", civlen ); + printf( "With nautical twilight %5.2f hours\n", nautlen ); + printf( "With astronomical twilight %5.2f hours\n", astrlen ); + printf( "Length of twilight: civil %5.2f hours\n", + (civlen-daylen)/2.0); + printf( " nautical %5.2f hours\n", + (nautlen-daylen)/2.0); + printf( " astronomical %5.2f hours\n", + (astrlen-daylen)/2.0); + + rs = sun_rise_set ( year, month, day, lon, lat, + &rise, &set ); + civ = civil_twilight ( year, month, day, lon, lat, + &civ_start, &civ_end ); + naut = nautical_twilight ( year, month, day, lon, lat, + &naut_start, &naut_end ); + astr = astronomical_twilight( year, month, day, lon, lat, + &astr_start, &astr_end ); + + printf( "Sun at south %5.2fh UT\n", (rise+set)/2.0 ); + + switch( rs ) + { + case 0: + printf( "Sun rises %5.2fh UT, sets %5.2fh UT\n", + rise, set ); + break; + case +1: + printf( "Sun above horizon\n" ); + break; + case -1: + printf( "Sun below horizon\n" ); + break; + } + + switch( civ ) + { + case 0: + printf( "Civil twilight starts %5.2fh, " + "ends %5.2fh UT\n", civ_start, civ_end ); + break; + case +1: + printf( "Never darker than civil twilight\n" ); + break; + case -1: + printf( "Never as bright as civil twilight\n" ); + break; + } + + switch( naut ) + { + case 0: + printf( "Nautical twilight starts %5.2fh, " + "ends %5.2fh UT\n", naut_start, naut_end ); + break; + case +1: + printf( "Never darker than nautical twilight\n" ); + break; + case -1: + printf( "Never as bright as nautical twilight\n" ); + break; + } + + switch( astr ) + { + case 0: + printf( "Astronomical twilight starts %5.2fh, " + "ends %5.2fh UT\n", astr_start, astr_end ); + break; + case +1: + printf( "Never darker than astronomical twilight\n" ); + break; + case -1: + printf( "Never as bright as astronomical twilight\n" ); + break; + } + + } +} + + +/* The "workhorse" function for sun rise/set times */ + +int __sunriset__( int year, int month, int day, double lon, double lat, + double altit, int upper_limb, double *trise, double *tset ) +/***************************************************************************/ +/* Note: year,month,date = calendar date, 1801-2099 only. */ +/* Eastern longitude positive, Western longitude negative */ +/* Northern latitude positive, Southern latitude negative */ +/* The longitude value IS critical in this function! */ +/* altit = the altitude which the Sun should cross */ +/* Set to -35/60 degrees for rise/set, -6 degrees */ +/* for civil, -12 degrees for nautical and -18 */ +/* degrees for astronomical twilight. */ +/* upper_limb: non-zero -> upper limb, zero -> center */ +/* Set to non-zero (e.g. 1) when computing rise/set */ +/* times, and to zero when computing start/end of */ +/* twilight. */ +/* *rise = where to store the rise time */ +/* *set = where to store the set time */ +/* Both times are relative to the specified altitude, */ +/* and thus this function can be used to comupte */ +/* various twilight times, as well as rise/set times */ +/* Return value: 0 = sun rises/sets this day, times stored at */ +/* *trise and *tset. */ +/* +1 = sun above the specified "horizon" 24 hours. */ +/* *trise set to time when the sun is at south, */ +/* minus 12 hours while *tset is set to the south */ +/* time plus 12 hours. "Day" length = 24 hours */ +/* -1 = sun is below the specified "horizon" 24 hours */ +/* "Day" length = 0 hours, *trise and *tset are */ +/* both set to the time when the sun is at south. */ +/* */ +/**********************************************************************/ +{ + double d, /* Days since 2000 Jan 0.0 (negative before) */ + sr, /* Solar distance, astronomical units */ + sRA, /* Sun's Right Ascension */ + sdec, /* Sun's declination */ + sradius, /* Sun's apparent radius */ + t, /* Diurnal arc */ + tsouth, /* Time when Sun is at south */ + sidtime; /* Local sidereal time */ + + int rc = 0; /* Return cde from function - usually 0 */ + + /* Compute d of 12h local mean solar time */ + d = days_since_2000_Jan_0(year,month,day) + 0.5 - lon/360.0; + + /* Compute local sideral time of this moment */ + sidtime = revolution( GMST0(d) + 180.0 + lon ); + + /* Compute Sun's RA + Decl at this moment */ + sun_RA_dec( d, &sRA, &sdec, &sr ); + + /* Compute time when Sun is at south - in hours UT */ + tsouth = 12.0 - rev180(sidtime - sRA)/15.0; + + /* Compute the Sun's apparent radius, degrees */ + sradius = 0.2666 / sr; + + /* Do correction to upper limb, if necessary */ + if ( upper_limb ) + altit -= sradius; + + /* Compute the diurnal arc that the Sun traverses to reach */ + /* the specified altitide altit: */ + { + double cost; + cost = ( sind(altit) - sind(lat) * sind(sdec) ) / + ( cosd(lat) * cosd(sdec) ); + if ( cost >= 1.0 ) + rc = -1, t = 0.0; /* Sun always below altit */ + else if ( cost <= -1.0 ) + rc = +1, t = 12.0; /* Sun always above altit */ + else + t = acosd(cost)/15.0; /* The diurnal arc, hours */ + } + + /* Store rise and set times - in hours UT */ + *trise = tsouth - t; + *tset = tsouth + t; + + return rc; +} /* __sunriset__ */ + + + +/* The "workhorse" function */ + + +double __daylen__( int year, int month, int day, double lon, double lat, + double altit, int upper_limb ) +/**********************************************************************/ +/* Note: year,month,date = calendar date, 1801-2099 only. */ +/* Eastern longitude positive, Western longitude negative */ +/* Northern latitude positive, Southern latitude negative */ +/* The longitude value is not critical. Set it to the correct */ +/* longitude if you're picky, otherwise set to to, say, 0.0 */ +/* The latitude however IS critical - be sure to get it correct */ +/* altit = the altitude which the Sun should cross */ +/* Set to -35/60 degrees for rise/set, -6 degrees */ +/* for civil, -12 degrees for nautical and -18 */ +/* degrees for astronomical twilight. */ +/* upper_limb: non-zero -> upper limb, zero -> center */ +/* Set to non-zero (e.g. 1) when computing day length */ +/* and to zero when computing day+twilight length. */ +/**********************************************************************/ +{ + double d, /* Days since 2000 Jan 0.0 (negative before) */ + obl_ecl, /* Obliquity (inclination) of Earth's axis */ + sr, /* Solar distance, astronomical units */ + slon, /* True solar longitude */ + sin_sdecl, /* Sine of Sun's declination */ + cos_sdecl, /* Cosine of Sun's declination */ + sradius, /* Sun's apparent radius */ + t; /* Diurnal arc */ + + /* Compute d of 12h local mean solar time */ + d = days_since_2000_Jan_0(year,month,day) + 0.5 - lon/360.0; + + /* Compute obliquity of ecliptic (inclination of Earth's axis) */ + obl_ecl = 23.4393 - 3.563E-7 * d; + + /* Compute Sun's position */ + sunpos( d, &slon, &sr ); + + /* Compute sine and cosine of Sun's declination */ + sin_sdecl = sind(obl_ecl) * sind(slon); + cos_sdecl = sqrt( 1.0 - sin_sdecl * sin_sdecl ); + + /* Compute the Sun's apparent radius, degrees */ + sradius = 0.2666 / sr; + + /* Do correction to upper limb, if necessary */ + if ( upper_limb ) + altit -= sradius; + + /* Compute the diurnal arc that the Sun traverses to reach */ + /* the specified altitide altit: */ + { + double cost; + cost = ( sind(altit) - sind(lat) * sin_sdecl ) / + ( cosd(lat) * cos_sdecl ); + if ( cost >= 1.0 ) + t = 0.0; /* Sun always below altit */ + else if ( cost <= -1.0 ) + t = 24.0; /* Sun always above altit */ + else t = (2.0/15.0) * acosd(cost); /* The diurnal arc, hours */ + } + return t; +} /* __daylen__ */ + + +/* This function computes the Sun's position at any instant */ + +void sunpos( double d, double *lon, double *r ) +/******************************************************/ +/* Computes the Sun's ecliptic longitude and distance */ +/* at an instant given in d, number of days since */ +/* 2000 Jan 0.0. The Sun's ecliptic latitude is not */ +/* computed, since it's always very near 0. */ +/******************************************************/ +{ + double M, /* Mean anomaly of the Sun */ + w, /* Mean longitude of perihelion */ + /* Note: Sun's mean longitude = M + w */ + e, /* Eccentricity of Earth's orbit */ + E, /* Eccentric anomaly */ + x, y, /* x, y coordinates in orbit */ + v; /* True anomaly */ + + /* Compute mean elements */ + M = revolution( 356.0470 + 0.9856002585 * d ); + w = 282.9404 + 4.70935E-5 * d; + e = 0.016709 - 1.151E-9 * d; + + /* Compute true longitude and radius vector */ + E = M + e * RADEG * sind(M) * ( 1.0 + e * cosd(M) ); + x = cosd(E) - e; + y = sqrt( 1.0 - e*e ) * sind(E); + *r = sqrt( x*x + y*y ); /* Solar distance */ + v = atan2d( y, x ); /* True anomaly */ + *lon = v + w; /* True solar longitude */ + if ( *lon >= 360.0 ) + *lon -= 360.0; /* Make it 0..360 degrees */ +} + +void sun_RA_dec( double d, double *RA, double *dec, double *r ) +{ + double lon, obl_ecl, x, y, z; + + /* Compute Sun's ecliptical coordinates */ + sunpos( d, &lon, r ); + + /* Compute ecliptic rectangular coordinates (z=0) */ + x = *r * cosd(lon); + y = *r * sind(lon); + + /* Compute obliquity of ecliptic (inclination of Earth's axis) */ + obl_ecl = 23.4393 - 3.563E-7 * d; + + /* Convert to equatorial rectangular coordinates - x is uchanged */ + z = y * sind(obl_ecl); + y = y * cosd(obl_ecl); + + /* Convert to spherical coordinates */ + *RA = atan2d( y, x ); + *dec = atan2d( z, sqrt(x*x + y*y) ); + +} /* sun_RA_dec */ + + +/******************************************************************/ +/* This function reduces any angle to within the first revolution */ +/* by subtracting or adding even multiples of 360.0 until the */ +/* result is >= 0.0 and < 360.0 */ +/******************************************************************/ + +#define INV360 ( 1.0 / 360.0 ) + +double revolution( double x ) +/*****************************************/ +/* Reduce angle to within 0..360 degrees */ +/*****************************************/ +{ + return( x - 360.0 * floor( x * INV360 ) ); +} /* revolution */ + +double rev180( double x ) +/*********************************************/ +/* Reduce angle to within +180..+180 degrees */ +/*********************************************/ +{ + return( x - 360.0 * floor( x * INV360 + 0.5 ) ); +} /* revolution */ + + +/*******************************************************************/ +/* This function computes GMST0, the Greenwhich Mean Sidereal Time */ +/* at 0h UT (i.e. the sidereal time at the Greenwhich meridian at */ +/* 0h UT). GMST is then the sidereal time at Greenwich at any */ +/* time of the day. I've generelized GMST0 as well, and define it */ +/* as: GMST0 = GMST - UT -- this allows GMST0 to be computed at */ +/* other times than 0h UT as well. While this sounds somewhat */ +/* contradictory, it is very practical: instead of computing */ +/* GMST like: */ +/* */ +/* GMST = (GMST0) + UT * (366.2422/365.2422) */ +/* */ +/* where (GMST0) is the GMST last time UT was 0 hours, one simply */ +/* computes: */ +/* */ +/* GMST = GMST0 + UT */ +/* */ +/* where GMST0 is the GMST "at 0h UT" but at the current moment! */ +/* Defined in this way, GMST0 will increase with about 4 min a */ +/* day. It also happens that GMST0 (in degrees, 1 hr = 15 degr) */ +/* is equal to the Sun's mean longitude plus/minus 180 degrees! */ +/* (if we neglect aberration, which amounts to 20 seconds of arc */ +/* or 1.33 seconds of time) */ +/* */ +/*******************************************************************/ + +double GMST0( double d ) +{ + double sidtim0; + /* Sidtime at 0h UT = L (Sun's mean longitude) + 180.0 degr */ + /* L = M + w, as defined in sunpos(). Since I'm too lazy to */ + /* add these numbers, I'll let the C compiler do it for me. */ + /* Any decent C compiler will add the constants at compile */ + /* time, imposing no runtime or code overhead. */ + sidtim0 = revolution( ( 180.0 + 356.0470 + 282.9404 ) + + ( 0.9856002585 + 4.70935E-5 ) * d ); + return sidtim0; +} /* GMST0 */ diff --git a/reference/C/CONTRIB/SNIP/tabtrick.c b/reference/C/CONTRIB/SNIP/tabtrick.c new file mode 100755 index 0000000..9186070 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/tabtrick.c @@ -0,0 +1,54 @@ +/* +** TABTRICKs.C - Demonstrates how to use printf() for columnar formatting +*/ + +#include <stdio.h> +#include <string.h> + +#define putnum(i) putchar(i+'0') + +void main() /* void main() is not standard C, but avoids warnings */ +{ + char *firstname[] = { "Aloysius", "Bob", "Dennis", NULL }, + *lastname[] = { "Fuddrucker", "Stout", "Ritchie", NULL }; + int score[] = { -10, 70, 200, 0 }, + i, tabwidth; + + printf("%15sStudent Name%30s\n\n", "", "Test Score"); + for (i = 0; NULL != lastname[i]; ++i) + { + tabwidth = 36 /* spaces to tab */ + -2 /* allow for ", " */ + -strlen(lastname[i]); /* lastname space */ + printf("%15s%s, %-*s%3d\n", + "", lastname[i], tabwidth, firstname[i], score[i]); + } + + /* print a ruler to make things clearer */ + + puts(""); + for (i = 0; i < 71; ++i) + { + if (i == 10 * (i / 10)) + putnum(i / 10); + else putchar(' '); + } + puts(""); + for (i = 0; i < 71; ++i) + putnum(i % 10); +} + +/* + +RESULTS: + + Student Name Test Score + + Fuddrucker, Aloysius -10 + Stout, Bob 70 + Ritchie, Dennis 200 + +0 1 2 3 4 5 6 7 +01234567890123456789012345678901234567890123456789012345678901234567890 + +*/ diff --git a/reference/C/CONTRIB/SNIP/tail.c b/reference/C/CONTRIB/SNIP/tail.c new file mode 100755 index 0000000..a932a58 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/tail.c @@ -0,0 +1,181 @@ +/* +** TAIL.C +** ---------------------------------------------------------------------- +** Display the last n lines of a file (20 lines by default). +** +** Revision history +** ================ +** Modified 19930604 by Ruurd Pels: +** - Increased default line numbers from 5 to 20 +** - Made ANSI C conformant (I hope) +** - Added '-' support for commandline +** - Outputs header to stderr instead of stdout to leave it out when +** redirecting files +** - Fixed \r\r\n bug for MSDOS machines +** +** Modified 19861005 by Joe Huffman: +** - Utilize prototyping, fixed a bug, added (a few) comments and help. +** +** Written 19860204 by Joe Huffman. +** +** Not copyrighted. +*/ + +#include <stdio.h> +#include <stdlib.h> + +char head1[] = {"\n------- \""}; +char head2[] = {" -------\n"}; +FILE * fp; +int filenum; +int cc; +unsigned int linenum = 20; +unsigned int indx; +long int * tail; + +/* +** Get the number of lines to display at the "tail" of each file from +** the command line. +*/ + +void getlinenum(int n, char * str[]) +{ + for (--n; n; --n) + { + ++str; + if ((**str == '/') || (**str == '-')) + { + linenum = atoi(*(str) + 1); + if (linenum <= 0) + linenum = 20; + } + } + + /* Because we save a pointer to the end of the PREVIOUS line */ + linenum++; +} + +/* +** Set the file pointer "fp" to "linenum - 1" lines before the end of +** the file. +*/ + +void gettail(void) +{ + unsigned char outstr[15]; + unsigned long int currline = 0L; + + tail = (long int *)malloc(sizeof(*tail) * linenum); + if (!tail) + { + fputs("Insufficient memory.", stderr); + exit(1); + } + tail[0] = ftell(fp); + indx = 0; + + for (cc = getc(fp); cc != EOF; cc = getc(fp)) + { + if (cc == '\r') + { + ++currline; + cc = getc(fp); + if (cc != '\n') + ungetc(cc, fp); + ++indx; + indx %= linenum; + tail[indx] = ftell(fp); + } + else + { + if (cc == '\n') + { + ++currline; + cc = getc(fp); + if (cc != '\r') + ungetc(cc, fp); + ++indx; + indx %= linenum; + tail[indx] = ftell(fp); + } + } + } + fputs("\" ", stderr); + ltoa(currline, outstr, 10); + fputs(outstr, stderr); + fputs(" lines", stderr); + if (currline >= linenum - 1) + { + indx++; + indx %= linenum; + } + else indx = 0; + + if (fseek(fp, tail[indx], 0) == -1) + { + fputs("\nFile seek error.", stderr); + exit(1); + } + free(tail); +} + +/* +** Tell the user what the program is and how to use it. +*/ + +void help(void) +{ + char *ptr; + static char help_str[] = "Usage:\n\nTAIL <filename> [filename] " + "[/n]\n\n<filename> - The name of a valid file, wildcards " + "accepted.\nn - Number of lines to print out, 20 " + "by default."; + + for (ptr = &help_str[0]; *ptr; ptr++) + fputc(*ptr, stdout); +} + +int main(int argc, char **argv) +{ + if (argc <= 1) + { + help(); + exit(1); + } + + getlinenum(argc, argv); + + for (filenum = 1; filenum < argc; ++filenum) + { + if (*argv[filenum] == '/') + continue; + fp = fopen(argv[filenum], "rb"); + if (!fp) + { + fputs(head1, stderr); + fputs(argv[filenum], stderr); + fputs("\" not found.", stderr); + fputs(head2, stderr); + } + else + { + fputs(head1, stderr); + fputs(argv[filenum], stderr); + gettail(); + fputs(head2, stderr); + for (cc = getc(fp); cc != EOF; cc = getc(fp)) + { +#ifdef __MSDOS__ + if (cc != '\r') + { + fputc(cc, stdout); + } +#else + fputc(cc, stdout); +#endif + } + fclose(fp); + } + } + return EXIT_SUCCESS; +} diff --git a/reference/C/CONTRIB/SNIP/tasker.c b/reference/C/CONTRIB/SNIP/tasker.c new file mode 100755 index 0000000..be34c7e --- /dev/null +++ b/reference/C/CONTRIB/SNIP/tasker.c @@ -0,0 +1,127 @@ +/* +** Tasker.C +** +** public domain by David Gibbs +*/ + +struct ts_os_ver t_os_ver[TOT_OS]; +int t_os_type; +int t_os; + +const char *t_os_name[TOT_OS] = { + "DOS", + "OS/2 DOS", + "DESQview", + "Windows Std", + "Windows 386" + }; + +int get_os (void) +{ + union REGS t_regs; + + t_os_type = 0; + t_os = 0; + + /* test for DOS or OS/2 */ + + if (_osmajor < 10) + { + t_os_ver[DOS].maj = _osmajor; + t_os_ver[DOS].min = _osminor; + t_os_type = t_os_type | is_DOS; + } + else + { + t_os_type = t_os_type | is_OS2; + t_os_ver[OS2].maj = _osmajor/10; + t_os_ver[OS2].min = _osminor; + } + + /* test for Windows */ + + t_regs.x.ax = 0x4680; + int86(0x2F, &t_regs, &t_regs); + + if (t_regs.x.ax == 0x0000) + { + t_os_ver[WINS].maj = 3; + t_os_ver[WINS].min = 0; + t_os_type = t_os_type | is_WINS; + } + else + { + t_regs.x.ax = 0x1600 ; + int86(0x2F, &t_regs, &t_regs); + + switch (t_regs.h.al) + { + case 0x00 : + case 0x80 : + case 0x01 : + case 0xFF : + break; + + default : + t_os_type = t_os_type | is_WIN3; + t_os_ver[WIN3].maj = t_regs.h.al; + t_os_ver[WIN3].min = t_regs.h.ah; + break ; + } /* endswitch */ + } /* endif */ + + /* Test for DESQview */ + + t_regs.x.cx = 0x4445; /* load incorrect date */ + t_regs.x.dx = 0x5351; + t_regs.x.ax = 0x2B01; /* DV set up call */ + + intdos(&t_regs, &t_regs); + if (t_regs.h.al != 0xFF) + { + t_os_type = t_os_type | is_DV; + t_os_ver[DV].maj = t_regs.h.bh; + t_os_ver[DV].min = t_regs.h.bl; + } + + if(t_os_type & is_DOS) + t_os = DOS; + + if(t_os_type & is_WINS) + t_os = WINS; + + if(t_os_type & is_WIN3) + t_os = WIN3; + + if(t_os_type & is_DV) + t_os = DV; + + if(t_os_type & is_OS2) + t_os = OS2; + + return(t_os-1); + +} + +void t_slice(void) +{ + union REGS t_regs; + + switch (t_os) + { + case DOS : + break; + + case OS2 : + case WIN3 : + case WINS : + t_regs.x.ax = 0x1680; + int86(0x2f,&t_regs,&t_regs); + break; + + case DV : + t_regs.x.ax = 0x1000; + int86(0x15,&t_regs,&t_regs); + break; + } /* switch(t_os) */ +} diff --git a/reference/C/CONTRIB/SNIP/tasker.h b/reference/C/CONTRIB/SNIP/tasker.h new file mode 100755 index 0000000..184e1af --- /dev/null +++ b/reference/C/CONTRIB/SNIP/tasker.h @@ -0,0 +1,44 @@ +/* +** Tasker.H +** +** public domain by David Gibbs +*/ + +#ifndef DG_TASKER +#define DG_TASKER + +struct ts_os_ver { + int maj; + int min; +}; + +#define TOT_OS 5 + +#define DOS 0 +#define OS2 1 +#define DV 2 +#define WINS 3 +#define WIN3 4 + + /* 76543210 */ +#define is_DOS 0x01 /* b'00000001' */ +#define is_OS2 0x02 /* b'00000010' */ +#define is_DV 0x04 /* b'00000100' */ +#define is_WINS 0x08 /* b'00001000' */ +#define is_WIN3 0x10 /* b'00010000' */ + + +extern int t_os_type; +extern int t_os; + +extern const char *t_os_name[TOT_OS]; + +extern struct ts_os_ver t_os_ver[TOT_OS]; + + +/* Function prototypes */ + +int get_os(); +void t_slice(); + +#endif /* DG_TASKER */ diff --git a/reference/C/CONTRIB/SNIP/tasker.txt b/reference/C/CONTRIB/SNIP/tasker.txt new file mode 100755 index 0000000..9f0b281 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/tasker.txt @@ -0,0 +1,78 @@ + Multi-Tasker Detection Routines + by David Gibbs + FidoNet: 1:115/439.0 + Internet: David.Gibbs@f439.n115.z1.fidonet.org + +The following is a set of C routines that will enable a programmer to +detect a mutli-tasking environment and release the time slice when +desired. Currently DESQview, Windows, & OS/2 are the environments +supported. + +Routines consist of two functions, two global int variables, one global +structure, and a table of character pointers. + +void t_get_os(); This routines detects the operating environment, sets +on the appropriate bits in the t_os_type field, and sets the t_os field +to the dominant environment. + +void t_slice(); This routine will release the remainder of the current +tasks time slice in the manner appropriate to the dominant envionment. + +The following fields & structures are available... + +int t_os_type; is a bit mapped integer that indicates the presence of +various operating envionments. If Bit 0 is on, DOS is present, Bit 1 = +OS2, bit 2 = DESQview, bit 3 = Windows standard, bit 4 = Windows 386 +Enh. These bits can be tested by using logical operations with the +symbolic constants is_DOS, is_OS2, is_DV, is_WINS, and is_WIN3. + +int t_os; represents the dominant environment. The dominant envionment +is defined as the multi-tasking system that takes precidence. For +instance, you can run Windows *UNDER* DESQview, but DESQview would be +dominant, the same goes true for OS/2 & Windows. This value can be +tested by comparing to the symbolic constants: DOS, OS2, DV, WINS, and +WIN3. + +struct t_os_ver ts_os_ver[]; indicates the versions of the various +environments present. Major & minor versions are found in the +structure members 'maj' and 'min'. The structure is subscripted, so you +can access the version of envionments using the symbolic constants use +in 't_os'. + +const char *t_os_name[]; contains the names of the environments +detectable. These too are subscripted and can be accessed using the +symbolic constants above. + +A sample program that uses these routines follows: + +#include <stdio.h> +#include "tasker.h" + +void main() { + get_os(); + + printf("%s %d.%d detected",t_os_name[t_os], + t_os_ver[t_os].maj, + t_os_ver[t_os].min); + + while(!kbhit()) { + printf("Hit a key!\r\n"); + t_slice(); + } +} + + +Special thanks go to Geoffery Booher (1:2270/233) for assistance with +Windows & OS/2 detection & Time slicing. + +This routine is released to the public as CommentWare - If you use it, +please send me a comment as to what you thought of it... oh yeah, you +might think of giving me credit for the routines. + +Also, if you can think of a enhancement or correction, please let me +know. I can be reached at the above mentioned email addresses. + +Copyrights: DESQview by Quarterdeck Office Systems + Windows by Microsoft + OS/2 by IBM + TurboC++ by Borland diff --git a/reference/C/CONTRIB/SNIP/testcmt.c b/reference/C/CONTRIB/SNIP/testcmt.c new file mode 100755 index 0000000..a5614e4 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/testcmt.c @@ -0,0 +1,16 @@ +/* testcmt.c - test getcmt.exe - C comment 1 */ +int i; +main() +{ + int j; + /* C comment 2 */ + int k; + /* C comment 3 */ + char ch2; /* C comment 4 */ char ch3; // C++ comment 1 + // C++ comment 2 + char ch4; + // C++ comment 3 + i = 0; + return(i); +} +/* end of testcmt.c - C comment 5 */ diff --git a/reference/C/CONTRIB/SNIP/timegetc.c b/reference/C/CONTRIB/SNIP/timegetc.c new file mode 100755 index 0000000..c41c45b --- /dev/null +++ b/reference/C/CONTRIB/SNIP/timegetc.c @@ -0,0 +1,44 @@ +/* +** TIMEGETC.C - waits for a given number of seconds for the user to press +** a key. Returns the key pressed, or EOF if time expires +** +** by Bob Jarvis +*/ + +#include <stdio.h> +#include <time.h> +#include <conio.h> + +int timed_getch(int n_seconds) +{ + time_t start, now; + + start = time(NULL); + now = start; + + while(difftime(now, start) < (double)n_seconds && !kbhit()) + { + now = time(NULL); + } + + if(kbhit()) + return getch(); + else return EOF; +} + +#ifdef TEST + +void main(void) +{ + int c; + + printf("Starting a 5 second delay...\n"); + + c = timed_getch(5); + + if(c == EOF) + printf("Timer expired\n"); + else printf("Key was pressed, c = '%c'\n", c); +} + +#endif /* TEST */ diff --git a/reference/C/CONTRIB/SNIP/toascii.c b/reference/C/CONTRIB/SNIP/toascii.c new file mode 100755 index 0000000..147daa4 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/toascii.c @@ -0,0 +1,37 @@ +int ascii2ebcdic[256] = { + 0, 1, 2, 3, 55, 45, 46, 47, 22, 5, 37, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 60, 61, 50, 38, 24, 25, 63, 39, 28, 29, 30, 31, + 64, 79,127,123, 91,108, 80,125, 77, 93, 92, 78,107, 96, 75, 97, + 240,241,242,243,244,245,246,247,248,249,122, 94, 76,126,110,111, + 124,193,194,195,196,197,198,199,200,201,209,210,211,212,213,214, + 215,216,217,226,227,228,229,230,231,232,233, 74,224, 90, 95,109, + 121,129,130,131,132,133,134,135,136,137,145,146,147,148,149,150, + 151,152,153,162,163,164,165,166,167,168,169,192,106,208,161, 7, + 32, 33, 34, 35, 36, 21, 6, 23, 40, 41, 42, 43, 44, 9, 10, 27, + 48, 49, 26, 51, 52, 53, 54, 8, 56, 57, 58, 59, 4, 20, 62,225, + 65, 66, 67, 68, 69, 70, 71, 72, 73, 81, 82, 83, 84, 85, 86, 87, + 88, 89, 98, 99,100,101,102,103,104,105,112,113,114,115,116,117, + 118,119,120,128,138,139,140,141,142,143,144,154,155,156,157,158, + 159,160,170,171,172,173,174,175,176,177,178,179,180,181,182,183, + 184,185,186,187,188,189,190,191,202,203,204,205,206,207,218,219, + 220,221,222,223,234,235,236,237,238,239,250,251,252,253,254,255 +}; + +int ebcdic2ascii[256] = { + 0, 1, 2, 3,156, 9,134,127,151,141,142, 11, 12, 13, 14, 15, + 16, 17, 18, 19,157,133, 8,135, 24, 25,146,143, 28, 29, 30, 31, + 128,129,130,131,132, 10, 23, 27,136,137,138,139,140, 5, 6, 7, + 144,145, 22,147,148,149,150, 4,152,153,154,155, 20, 21,158, 26, + 32,160,161,162,163,164,165,166,167,168, 91, 46, 60, 40, 43, 33, + 38,169,170,171,172,173,174,175,176,177, 93, 36, 42, 41, 59, 94, + 45, 47,178,179,180,181,182,183,184,185,124, 44, 37, 95, 62, 63, + 186,187,188,189,190,191,192,193,194, 96, 58, 35, 64, 39, 61, 34, + 195, 97, 98, 99,100,101,102,103,104,105,196,197,198,199,200,201, + 202,106,107,108,109,110,111,112,113,114,203,204,205,206,207,208, + 209,126,115,116,117,118,119,120,121,122,210,211,212,213,214,215, + 216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231, + 123, 65, 66, 67, 68, 69, 70, 71, 72, 73,232,233,234,235,236,237, + 125, 74, 75, 76, 77, 78, 79, 80, 81, 82,238,239,240,241,242,243, + 92,159, 83, 84, 85, 86, 87, 88, 89, 90,244,245,246,247,248,249, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,250,251,252,253,254,255 +}; diff --git a/reference/C/CONTRIB/SNIP/todaybak.c b/reference/C/CONTRIB/SNIP/todaybak.c new file mode 100755 index 0000000..ab3ffb6 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/todaybak.c @@ -0,0 +1,98 @@ +/* +** TODAYBAK.C - Back up today's work to a specified floppy +** +** public domain demo by Bob Stout +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <dos.h> + +#if defined(__ZTC__) && (__ZTC__ < 0x600) + #define _dos_getdate dos_getdate + #define _dos_setdate dos_setdate + #define _dosdate_t dos_date_t +#endif +#ifdef __TURBOC__ + #define _dosdate_t dosdate_t +#endif + +#ifndef SUCCESS + #define SUCCESS 0 +#endif + +#ifndef CAST + #define CAST(new_type,old_object) (*((new_type *)&(old_object))) +#endif + +#define LAST_CHAR(s) (((char *)s)[strlen(s) - 1]) + +struct DOS_DATE { + unsigned int da : 5; + unsigned int mo : 4; + unsigned int yr : 7; + } ; + +struct _dosdate_t today; +struct DOS_DATE ftoday; +char drive; + +void do_dir(char *); +void usage(void); + +int main(int argc, char *argv[]) +{ + int i; + + _dos_getdate(&today); + ftoday.da = today.day; + ftoday.mo = today.month; + ftoday.yr = today.year - 1980; + + if (2 > argc) + usage(); + + drive = *argv[1]; + if (!strchr("AaBb", drive)) + usage(); + + if (3 > argc) + do_dir("."); + else for (i = 2; i < argc; ++i) + do_dir(argv[i]); + + return EXIT_SUCCESS; +} + +void usage(void) +{ + puts("usage: TODAYBAK floppy [dir1] [...dirN]"); + puts(" Copies today's files to the specified floppy."); + puts(" floppy = 'A' | 'B'"); + puts(" with no directories specified, " + "uses current directory"); + exit(EXIT_FAILURE); +} + +void do_dir(char *path) +{ + char search[67]; + struct find_t ff; + + strcat(strcpy(search, path), "\\*.*"); + if (SUCCESS == _dos_findfirst(search, 0xff, &ff)) do + { + if (!(ff.attrib & _A_SUBDIR) && '.' != *ff.name) + { + if (ff.wr_date == CAST(unsigned short, ftoday)) + { + char cmd[128]; + + sprintf(cmd, "COPY %s\\%s %c: > NUL", + path, ff.name, drive); + system(cmd); + } + } + } while (SUCCESS == _dos_findnext(&ff)); +} diff --git a/reference/C/CONTRIB/SNIP/toolkit.h b/reference/C/CONTRIB/SNIP/toolkit.h new file mode 100755 index 0000000..d7ba5a7 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/toolkit.h @@ -0,0 +1,66 @@ +/* +** This is a copyrighted work which is functionally identical to work +** originally published in Micro Cornucopia magazine (issue #52, March-April, +** 1990) and is freely licensed by the author, Walter Bright, for any use. +*/ + +/*_ toolkit.h Tue Apr 18 1989 Modified by: Walter Bright */ + +#ifndef TOOLKIT_H +#define TOOLKIT_H + +/* Define stuff that's different between machines. + * PROTOTYPING 1 if compiler supports prototyping + * HOSTBYTESWAPPED 1 if on the host machine the bytes are + * swapped (1 for 6809, 68000, 0 for 8088 + * and VAX). + */ + +#ifdef MSDOS +#define PROTOTYPING 1 +#define HOSTBYTESWAPPED 0 + +#define BITSPERBYTE 8 +#define SIZEOFINT sizeof(int) +#define SIZEOFLONG sizeof(long) + +#else +#ifdef M_UNIX /* SCO UNIX using Microsoft C. */ +#define PROTOTYPING 1 +#define HOSTBYTESWAPPED 0 +#define EXIT_SUCCESS 0 +#define EXIT_FAILURE 1 + +#define BITSPERBYTE 8 +#define SIZEOFINT sizeof(int) +#define SIZEOFLONG sizeof(long) +#else /* NOTE: host.h is *NOT* included in SNIPPETS */ +#include "host.h" /* Compiler/environment-specific stuff goes here */ +#endif + +#endif + +/* Static definitions do not appear in the linker .MAP file. Override */ +/* the definition here to make them global if necessary. */ +#ifndef STATIC +#define STATIC static +#endif + +#define arraysize(array) (sizeof(array) / sizeof(array[0])) + +/* Macros so that we can do prototyping, but still work with non- */ +/* prototyping compilers: */ + +#if PROTOTYPING +#define P(s) s +#else +#define P(s) () +#endif + +#ifdef DEBUG +#define debug(a) (a) +#else +#define debug(a) +#endif + +#endif /* TOOLKIT_H */ diff --git a/reference/C/CONTRIB/SNIP/touch.c b/reference/C/CONTRIB/SNIP/touch.c new file mode 100755 index 0000000..0f21d19 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/touch.c @@ -0,0 +1,63 @@ +/*----------------------------------------------------------------------* +* Program: touch * +* Programmer: Ray L. McVay * +* Started: 8 Aug 91 * +* Updated: 13 Feb 93 Thad Smith * +* Updated: 15 Feb 93 Bob Stout * +*-----------------------------------------------------------------------* +* Simple touch program to test BC time stamping function. * +* Public Domain * +*----------------------------------------------------------------------*/ + +#include <stdio.h> +#include <stdlib.h> +#include <time.h> +#ifdef __TURBOC__ + #include <dos.h> + #include <io.h> +#else + #include "ftime.h" /* Borland work-alike in SNIPPETS */ +#endif + +void usage(void); + +main(int argc, char **argv) +{ + time_t tnow; + struct tm tmnow; + struct ftime ft; + FILE *f; + + if (argc < 2) + usage(); + + tnow = time(NULL); + tmnow = *localtime(&tnow); + + ft.ft_year = tmnow.tm_year - 80; + ft.ft_month = tmnow.tm_mon + 1; + ft.ft_day = tmnow.tm_mday; + ft.ft_hour = tmnow.tm_hour; + ft.ft_min = tmnow.tm_min; + ft.ft_tsec = tmnow.tm_sec/2; + + if ((f = fopen(argv[1], "r+b")) != NULL) + setftime(fileno(f), &ft); + else if ((f = fopen(argv[1], "w")) != NULL) + setftime(fileno(f), &ft); + else perror("Can't open file"); + + if (f) + fclose(f); + + return EXIT_SUCCESS; +} + +void usage(void) +{ + puts("Usage: TOUCH filename\n"); + puts(" The timestamp of filename will be set to the current time."); + puts(" A zero-length file will be created if the file doesn't exist."); + exit(EXIT_FAILURE); +} + diff --git a/reference/C/CONTRIB/SNIP/tp6tod.c b/reference/C/CONTRIB/SNIP/tp6tod.c new file mode 100755 index 0000000..cdc9154 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/tp6tod.c @@ -0,0 +1,74 @@ +/* +** Convert Turbo Pascal 6-byte reals to C double format +** Written by Thad Smith III, Boulder, CO. 12/91 +** Tested on TC 2.01, BC++ 2.0/3.0, QC 2.50, Power C 2.0.1, ZTC 3.0 +** Contributed to the Public Domain. +*/ + +#include <math.h> +#include <string.h> +#ifdef TEST + #include <stdio.h> +#endif + +/* +** Specify packed structures. +** Note: This may not work on some compilers. +*/ + +#if __TURBOC__ > 0x0201 + #pragma option -a- +#elif defined __ZTC__ + #pragma ZTC align 1 +#else /* MSC, WATCOM */ + #pragma pack(1) +#endif + +double tp6_to_double(const unsigned char *tp6) +{ + struct { + unsigned char be ; /* biased exponent */ + unsigned int v1 ; /* lower 16 bits of mantissa */ + unsigned int v2 ; /* next 16 bits of mantissa */ + unsigned int v3:7; /* upper 7 bits of mantissa */ + unsigned int s :1; /* sign bit */ + } real; + + memcpy (&real, tp6, 6); + if (real.be == 0) + return 0.0; + return (((((128 +real.v3) * 65536.0) + real.v2) * 65536.0 + real.v1) * + ldexp ((real.s? -1.0: 1.0), real.be - (129+39))); +} + +#ifdef TEST + +/* +** This test program reads 6-byte values, one per line, in +** 12-digit hexadecimal format from stdin, converts to a double, +** then prints it. +*/ + +void main(void) +{ + unsigned char c[6]; + int buf[6]; + int i, n; + + for (;;) + { + n = scanf (" %2x%2x%2x%2x%2x%2x", &buf[0], &buf[1], &buf[2], + &buf[3], &buf[4], &buf[5]); + if (n <= 0) + break; + for (i=0; i < 6; i++) + { + c [i] = buf[i]; + printf ("%2.2x", buf[i]); + } + printf (" = %lg\n", tp6_to_double (c)); + } + return 0; +} + +#endif diff --git a/reference/C/CONTRIB/SNIP/translat.c b/reference/C/CONTRIB/SNIP/translat.c new file mode 100755 index 0000000..e9aa3a0 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/translat.c @@ -0,0 +1,71 @@ +/* +** Public Domain by Jerry Coffin. +** +** Interpets a string in a manner similar to that the compiler +** does string literals in a program. All escape sequences are +** longer than their translated equivalant, so the string is +** translated in place and either remains the same length or +** becomes shorter. +*/ + +#include <string.h> +#include <stdio.h> + +char *translate(char *string) +{ + char *here=string; + size_t len=strlen(string); + int num; + int numlen; + + while (NULL!=(here=strchr(here,'\\'))) + { + numlen=1; + switch (here[1]) + { + case '\\': + break; + + case 'r': + *here = '\r'; + break; + + case 'n': + *here = '\n'; + break; + + case 't': + *here = '\t'; + break; + + case 'v': + *here = '\v'; + break; + + case 'a': + *here = '\a'; + break; + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + numlen = sscanf(here,"%o",&num); + *here = (char)num; + break; + + case 'x': + numlen = sscanf(here,"%x",&num); + *here = (char) num; + break; + } + num = here - string + numlen; + here++; + memmove(here,here+numlen,len-num ); + } + return string; +} diff --git a/reference/C/CONTRIB/SNIP/trapdemo.c b/reference/C/CONTRIB/SNIP/trapdemo.c new file mode 100755 index 0000000..68c7387 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/trapdemo.c @@ -0,0 +1,74 @@ +/* +** Demonstrate TRAPFLAG.ASM +** +** public domain by Bob Stout +*/ + +#include <stdio.h> +#include <dos.h> +#include <int.h> + +extern void ins09(void); +extern void undo09(void); + +extern volatile int far ccrcvd; + +static void biosprt(char *p) +{ + union REGS regs; + + while (*p) + { + regs.h.ah = 0x0e; /* Low-level services only! */ + regs.h.al = *p++; + regs.x.bx = 0; + int86(0x10, ®s, ®s); + } +} + +static void far my_cc(void) +{ + char *p1 = "Ctrl-"; + char *p2 = "C"; + char *p3 = "Break"; + char *p4 = " received\r\n"; + + biosprt(p1); + if (1 == ccrcvd) + biosprt(p2); + else biosprt(p3); + biosprt(p4); +} + +main() +{ + unsigned seg, ofs; + int ch = 0; + + setbuf(stdout, NULL); + my_cc(); + ins09(); + atexit(undo09); + puts("New Ints 09h & 1Bh installed..."); + puts("Hit Esc to quit..."); + do + { + if (kbhit()) + { + if (0x1b != (ch = getch())) + { + if (0x20 > ch) + { + fputc('^', stdout); + ch += '@'; + } + fputc(ch, stdout); + } + } + if (ccrcvd) + { + my_cc(); + ccrcvd = 0; + } + } while (0x1b != ch); +} diff --git a/reference/C/CONTRIB/SNIP/trapflag.asm b/reference/C/CONTRIB/SNIP/trapflag.asm new file mode 100755 index 0000000..472f3b6 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/trapflag.asm @@ -0,0 +1,133 @@ + PAGE ,132 + +; Install a custom Interrupt 23 (Ctrl-C exception) handler +; +; Public domain by Bob Stout +; +; Requires MASM 5.1 or later or equivalent +; +; Assemble with: MASM /Mx /z ... +; TASM /jMASM /mx /z ... + +% .MODEL memodel,C ;Add model support via command + ;line macros, e.g. + ;MASM /Dmemodel=LARGE + +kbstatseg equ 40h +kbstatofs equ 17h +ctl_on equ 0100b +alt_on equ 1000b +sk_c equ 2eh +EOI equ 20h +PIC equ 20h +kb_inp equ 60h +kb_outp equ 61h + + .CODE + +_oldvec09 dd ? +_oldvec1b dd ? + + public ccrcvd + +ccrcvd dw 0 + +; +; This is our actual ISR +; +myint09: + push ax ;save AX... + pushf ; ...& flags + in al,kb_inp ;get scan code + cmp al,sk_c ;'C'? + jne do_old ;no, forget it + + push ax ;yes, save it... + push es ;...& ES reg + mov ax,kbstatseg ;read keyboard status from 40:17 + mov es,ax + mov al,es:kbstatofs + test al,ctl_on ;Ctrl pressed? + pop es ;(restore AX, ES) + pop ax + jz do_old ;no, forget it + + in al,kb_outp ;yes, toggle keyboard acknowledge line + mov ah,al + or al,80h + out kb_outp,al + xchg al,ah + out kb_outp,al + cli + mov ax,EOI ;send end-of-interrupt code + out PIC,al + mov ax,1 + mov CS:ccrcvd,ax + pop ax ;discard original flags... + pop ax ; ...& AX + iret ;all done +do_old: + popf ;restore flags... + pop ax ; ...& AX + jmp dword PTR CS:_oldvec09 ;call our handler + +; +; To avoid keyboard confusion, trap Ctrl-Break separately +; +myint1b: + push ax + pushf + mov ax,-1 + mov CS:ccrcvd,ax + popf + pop ax + iret + +; +; Call this to uninstall our ISR +; +undo09 PROC USES DX DS AX + mov dx, word PTR CS:_oldvec09 ;restore original keyboard vector + mov ds, word PTR CS:_oldvec09+2 + mov ax,2509h + int 21h + + mov dx, word PTR CS:_oldvec1b ;restore original keyboard vector + mov ds, word PTR CS:_oldvec1b+2 + mov ax,251bh + int 21h + + ret +undo09 ENDP + +; +; Call this to install our ISR +; +ins09 PROC USES AX BX DS ES + + mov ax,3509h ;get old keyboard ISR vector... + int 21h + mov word PTR CS:_oldvec09,bx + mov word PTR CS:_oldvec09+2,es ;...and save it + + mov ax,351bh ;get old exit vector... + int 21h + mov word PTR CS:_oldvec1b,bx + mov word PTR CS:_oldvec1b+2,es ;...and save it + + push cs ;get myint09 segment in DS + pop ds + mov dx, OFFSET myint09 ;install myint09 in int 09h + mov ax,2509h + int 21h + + push cs ;get myint1b segment in DS + pop ds + mov dx, OFFSET myint1b ;install myint1b in int 1bh + mov ax,251bh + int 21h + + ret +ins09 ENDP + + end diff --git a/reference/C/CONTRIB/SNIP/treedir.c b/reference/C/CONTRIB/SNIP/treedir.c new file mode 100755 index 0000000..268329c --- /dev/null +++ b/reference/C/CONTRIB/SNIP/treedir.c @@ -0,0 +1,53 @@ +/* +** TREEDIR.C - simple recursive directory lister +** +** public domain demo by Bob Stout +*/ + +#include <stdio.h> +#include <string.h> + +#ifdef __ZTC__ + #include <dos.h> + #ifndef _A_SUBDIR + #define _A_SUBDIR FA_DIREC + #endif +#elif defined(__TURBOC__) + #include <dir.h> + #include <dos.h> + #define _dos_findfirst(f,a,b) findfirst(f,b,a) + #define _dos_findnext(b) findnext(b) + #define find_t ffblk + #define _A_SUBDIR FA_DIREC + #define attrib ff_attrib + #define name ff_name +#else /* assume MSC/QC */ + #include <dos.h> + #include <errno.h> +#endif + +#ifndef SUCCESS + #define SUCCESS 0 +#endif + +void do_dir(char *path) +{ + char search[67], new[67]; + struct find_t ff; + + strcat(strcpy(search, path), "\\*.*"); + if (SUCCESS == _dos_findfirst(search, 0xff, &ff)) do + { + printf("%s\\%s\n", path, ff.name); + if (ff.attrib & _A_SUBDIR && '.' != *ff.name) + { + strcat(strcat(strcpy(new, path), "\\"), ff.name); + do_dir(new); + } + } while (SUCCESS == _dos_findnext(&ff)); +} + +void main(void) /* simple resursive current directory lister */ +{ + do_dir("."); +} diff --git a/reference/C/CONTRIB/SNIP/trim.c b/reference/C/CONTRIB/SNIP/trim.c new file mode 100755 index 0000000..dd331db --- /dev/null +++ b/reference/C/CONTRIB/SNIP/trim.c @@ -0,0 +1,78 @@ +/* +** TRIM.C - Remove leading, trailing, & excess embedded spaces +** +** public domain by Bob Stout +*/ + +#include <ctype.h> +#include <string.h> + +#define NUL '\0' + +char *trim(char *str) +{ + char *ibuf = str, *obuf = str; + int i = 0, cnt = 0; + + /* + ** Trap NULL + */ + + if (str) + { + /* + ** Remove leading spaces (from RMLEAD.C) + */ + + for (ibuf = str; *ibuf && isspace(*ibuf); ++ibuf) + ; + if (str != ibuf) + memmove(str, ibuf, ibuf - str); + + /* + ** Collapse embedded spaces (from LV1WS.C) + */ + + while (*ibuf) + { + if (isspace(*ibuf) && cnt) + ibuf++; + else + { + if (!isspace(*ibuf)) + cnt = 0; + else + { + *ibuf = ' '; + cnt = 1; + } + obuf[i++] = *ibuf++; + } + } + obuf[i] = NUL; + + /* + ** Remove trailing spaces (from RMTRAIL.C) + */ + + while (--i >= 0) + { + if (!isspace(obuf[i])) + break; + } + obuf[++i] = NUL; + } + return str; +} + +#ifdef TEST + +#include <stdio.h> + +main(int argc, char *argv[]) +{ + printf("trim(\"%s\") ", argv[1]); + printf("returned \"%s\"\n", trim(argv[1])); +} + +#endif /* TEST */ diff --git a/reference/C/CONTRIB/SNIP/truename.c b/reference/C/CONTRIB/SNIP/truename.c new file mode 100755 index 0000000..2e4d1e3 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/truename.c @@ -0,0 +1,103 @@ +/* +** Apologies for the grotty code; I only just whipped this up. +** +** tname.c -- wrapper for the undocumented DOS function TRUENAME +** +** TRUENAME: interrupt 0x21 function 0x60 +** +** Call with: ah = 60h +** es:di -> destination buffer +** ds:si -> source buffer +** +** Returns: carry bit set if there were problems +** +** This code hereby contributed to the public domain. +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#include <dos.h> + +#ifdef __TURBOC__ + #define _far far +#endif + +/* +** Strip leading and trailing blanks from a string. +*/ + +char _far *strip(char _far *s) +{ + char _far *end; + + for ( ; isspace(*s); s++) + ; + + for (end = s; *end; end++) + ; + + for (end--; isspace(*end); *end-- = '\0') + ; + + return s; +} + +/* +** Truename itself. Note that I'm using intdosx() rather than +** playing with some inline assembler -- I've discovered some +** people that actually don't have an assembler, poor bastards :-) +*/ + +char _far *truename(char _far *dst, char _far *src) +{ + union REGS rg; + struct SREGS rs; + + if (!src || !*src || !dst) + return NULL; + + src=strip(src); + + rg.h.ah=0x60; + rg.x.si=FP_OFF(src); + rg.x.di=FP_OFF(dst); + rs.ds=FP_SEG(src); + rs.es=FP_SEG(dst); + + intdosx(&rg,&rg,&rs); + + return (rg.x.cflag) ? NULL : dst; +} + +#ifdef TEST + +/* +** ... and a little test function. +*/ + +int main(int argc, char *argv[]) +{ + char buf[128]=" ", _far *s; + int i; + + if (3 > _osmajor) + { + puts("Only works with DOS 3+"); + return -1; + } + if(argc > 1) + { + for(i = 1; i < argc; i++) + { + s = truename((char _far *)buf,(char _far *)argv[i]); + printf("%s=%s\n",argv[i], s ? buf : "(null)"); + } + } + else printf("Usage: TRUENAME [filename [filename...]]\n"); + + return 0; +} + +#endif diff --git a/reference/C/CONTRIB/SNIP/uclock.c b/reference/C/CONTRIB/SNIP/uclock.c new file mode 100755 index 0000000..0b0058c --- /dev/null +++ b/reference/C/CONTRIB/SNIP/uclock.c @@ -0,0 +1,106 @@ +/* +** UCLOCK.C +** +** Contains routines to perform microsecond accuracy timing +** operations. +** +** Adapted from public domain source originally by David L. Fox +** Modified by Bob Stout +*/ + +#include "uclock.h" + +/* Constants */ + +#define CONTVAL 0x34 /* == 00110100 Control byte for 8253 timer. */ + /* Sets timer 0 to 2-byte read/write, */ + /* mode 2, binary. */ +#define T0DATA 0x40 /* Timer 0 data port address. */ +#define TMODE 0x43 /* Timer mode port address. */ +#define BIOS_DS 0x40 /* BIOS data segment. */ +#define B_TIKP 0x6c /* Address of BIOS (18.2/s) tick count. */ +#define SCALE 10000 /* Scale factor for timer ticks. */ + +/* The following values assume 18.2 BIOS ticks per second resulting from + the 8253 being clocked at 1.19 MHz. */ + +#define us_BTIK 54925 /* Micro sec per BIOS clock tick. */ +#define f_BTIK 4595 /* Fractional part of usec per BIOS tick. */ +#define us_TTIK 8381 /* Usec per timer tick * SCALE. (4/4.77 MHz) */ + +static int init = 0; + +/* +** usec_clock() +** +** An analog of the clock() function, usec_clock() returns a number of +** type uclock_t (defined in UCLOCK.H) which represents the number of +** microseconds past midnight. Analogous to CLK_TCK is UCLK_TCK, the +** number which a usec_clock() reading must be divided by to yield +** a number of seconds. +*/ + +uclock_t usec_clock(void) +{ + unsigned char msb, lsb; + unsigned int tim_ticks; + static uclock_t last, init_count; + static uclock_t far *c_ptr; + uclock_t count, us_tmp; + + if (!init) + { + c_ptr = (uclock_t far *)MK_FP(BIOS_DS, B_TIKP); + init = 1; /* First call, we have to set up timer. */ + int_off(); + outp(TMODE, CONTVAL); /* Write new control byte. */ + outp(T0DATA, 0); /* Initial count = 65636. */ + outp(T0DATA, 0); + init_count = *c_ptr; + int_on(); + return 0; /* First call returns zero. */ + } + + /* Read PIT channel 0 count - see text */ + + int_off(); /* Don't want an interrupt while getting time. */ + outp(TMODE, 0); /* Latch count. */ + lsb = (unsigned char)inp(T0DATA); /* Read count. */ + msb = (unsigned char)inp(T0DATA); + + /* Get BIOS tick count (read BIOS ram directly for speed and + to avoid turning on interrupts). */ + + count = *c_ptr; + int_on(); /* Interrupts back on. */ + if ((-1) == init) /* Restart count */ + { + init_count = count; + init = 1; + } + + /* Merge PIT channel 0 count with BIOS tick count */ + + if (count < init_count) + count += last; + else last = count; + count -= init_count; + tim_ticks = (unsigned)(-1) - ((msb << 8) | lsb); + us_tmp = count * us_BTIK; + return (us_tmp + ((long)tim_ticks * us_TTIK + us_tmp % SCALE) / SCALE); +} + +/* +** restart_uclock() +** +** Since usec_clock() bases its return value on a differential value, +** a potential exists for problems in programs which run continuously +** for more than 24 hours. In such an application, it's necessary, at +** least once a day, to reset usec_clock's starting count. +*/ + +void restart_uclock(void) +{ + if (init) + init = -1; +} diff --git a/reference/C/CONTRIB/SNIP/uclock.h b/reference/C/CONTRIB/SNIP/uclock.h new file mode 100755 index 0000000..a7e797c --- /dev/null +++ b/reference/C/CONTRIB/SNIP/uclock.h @@ -0,0 +1,53 @@ +/* +** UCLOCK.H +** +** Original Copyright 1988-1991 by Bob Stout as part of +** the MicroFirm Function Library (MFL) +** +** This subset version is functionally identical to the +** version originally published by the author in Tech Specialist +** magazine and is hereby donated to the public domain. +*/ + +#include <dos.h> +#include <time.h> + +#if defined(__ZTC__) + #include <int.h> + #undef int_on + #undef int_off +#elif defined(__TURBOC__) + #define int_on enable + #define int_off disable + #ifndef inp + #define inp inportb + #endif + #ifndef outp + #define outp outportb + #endif +#else /* assume MSC/QC */ + #include <conio.h> + #define int_on _enable + #define int_off _disable + #ifndef MK_FP + #define MK_FP(seg,offset) \ + ((void far *)(((unsigned long)(seg)<<16) | (unsigned)(offset))) + #endif +#endif + +/* ANSI-equivalent declarations and prototypes */ + +typedef unsigned long uclock_t; + +#define UCLK_TCK 1000000L /* Usec per second - replaces CLK_TCK */ + +#if __cplusplus + extern "C" { +#endif + +uclock_t usec_clock(void); +void restart_uclock(void); + +#if __cplusplus + } +#endif diff --git a/reference/C/CONTRIB/SNIP/unix2dos.c b/reference/C/CONTRIB/SNIP/unix2dos.c new file mode 100755 index 0000000..739d096 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/unix2dos.c @@ -0,0 +1,15 @@ +/* +** UNIX2DOS.C - Convert Unix-style pathnames to DOS-style +** +** public domain by Bob Stout +*/ + +char *unix2dos(char *path) +{ + char *p; + + for (p = path; *p; ++p) + if ('/' == *p) + *p = '\\'; + return path; +} diff --git a/reference/C/CONTRIB/SNIP/uudecode.c b/reference/C/CONTRIB/SNIP/uudecode.c new file mode 100755 index 0000000..01a8518 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/uudecode.c @@ -0,0 +1,41 @@ +/* +** by: John Lots +** patched up for BC++ 3.1 by Alan Eldridge 10/12/92 +** (UUCP: alane@wozzle.linet.org, FIDO: 1:272/38.473) +*/ + +#include <stdio.h> +#include <stdlib.h> +#define DEC(c) (char)(((c)-' ')&077) + +int main() +{ + int n; + char buf[128],a,b,c,d; + + scanf("begin %o ", &n); + gets(buf); /* filename */ + if (!freopen(buf, "wb", stdout)) /* oops.. */ + { + perror(buf); + exit(1); + } + while ((n=getchar())!=EOF&&((n=DEC(n))!=0)) + { + while (n>0) + { + a=DEC(getchar()); + b=DEC(getchar()); + c=DEC(getchar()); + d=DEC(getchar()); + if (n-->0) + putchar((a<<2)|(b>>4)); + if (n-->0) + putchar((b<<4)|(c>>2)); + if (n-->0) + putchar((c<<6)|d); + } + n=getchar(); /* skip \n */ + } + return 0; +} diff --git a/reference/C/CONTRIB/SNIP/uuencode.c b/reference/C/CONTRIB/SNIP/uuencode.c new file mode 100755 index 0000000..d634134 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/uuencode.c @@ -0,0 +1,146 @@ +/* uuencode.c */ + +/* +uudecode and uuencode are easily implemented under MSDOS as well. Here +are the sources for Microsoft C v3.0, but if you have another kind of C +compiler, there should be perhaps only 1 change -- the output file of +uudecode and the input file of uuencode must be in binary format. +(ie. binary files, like .EXE files may have byte patterns that are the +same as ^Z, which signals end-of-file in non-binary (text) mode). + + Don Kneller +UUCP: ...ucbvax!ucsfcgl!kneller +ARPA: kneller@ucsf-cgl.ARPA +BITNET: kneller@ucsfcgl.BITNET + + patched up for BC++ 3.1 by Alan Eldridge 10/12/92 + (UUCP: alane@wozzle.linet.org, FIDO: 1:272/38.473) + +*/ + +#ifndef lint +#ifndef MSDOS +static char sccsid[] = "@(#)uuencode.c 5.1 (Berkeley) 7/2/83"; +#endif +#endif + +/* + * uuencode [input] output + * + * Encode a file so it can be mailed to a remote system. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <sys/stat.h> + +/* ENC is the basic 1 character encoding function to make a char printing */ + +#define ENC(c) (((c) & 077) + ' ') + +void encode(FILE *in, FILE *out); +void outdec(char *p, FILE *f); +int fr(FILE *fd, char *buf, int cnt); + +main(int argc, char *argv[]) +{ + FILE *in; + struct stat sbuf; + int mode; + + /* optional 1st argument */ + + if (argc > 2) + { +#ifdef MSDOS + /* Use binary mode */ + if ((in = fopen(argv[1], "rb")) == NULL) + { +#else + if ((in = fopen(argv[1], "r")) == NULL) + { +#endif + perror(argv[1]); + exit(1); + } + argv++; argc--; + } + else in = stdin; + + if (argc != 2) + { + printf("Usage: uuencode [infile] remotefile\n"); + exit(2); + } + + /* figure out the input file mode */ + + fstat(fileno(in), &sbuf); + mode = sbuf.st_mode & 0777; + printf("begin %o %s\n", mode, argv[1]); + + encode(in, stdout); + + printf("end\n"); + return 0; +} + +/* + * copy from in to out, encoding as you go along. + */ + +void encode(FILE *in, FILE *out) +{ + char buf[80]; + int i, n; + + for (;;) + { + /* 1 (up to) 45 character line */ + + n = fr(in, buf, 45); + putc(ENC(n), out); + + for (i = 0; i < n; i += 3) + outdec(&buf[i], out); + + putc('\n', out); + if (n <= 0) + break; + } +} + +/* + * output one group of 3 bytes, pointed at by p, on file f. + */ + +void outdec(char *p, FILE *f) +{ + int c1, c2, c3, c4; + + c1 = *p >> 2; + c2 = ((p[0] << 4) & 060) | ((p[1] >> 4) & 017); + c3 = ((p[1] << 2) & 074) | ((p[2] >> 6) & 03); + c4 = p[2] & 077; + putc(ENC(c1), f); + putc(ENC(c2), f); + putc(ENC(c3), f); + putc(ENC(c4), f); +} + +/* fr: like read but stdio */ + +int fr(FILE *fd, char *buf, int cnt) +{ + int c, i; + + for (i = 0; i < cnt; i++) + { + c = getc(fd); + if (c == EOF) + return(i); + buf[i] = (char)c; + } + return (cnt); +} diff --git a/reference/C/CONTRIB/SNIP/vfname.c b/reference/C/CONTRIB/SNIP/vfname.c new file mode 100755 index 0000000..f0e083c --- /dev/null +++ b/reference/C/CONTRIB/SNIP/vfname.c @@ -0,0 +1,226 @@ +/* +** VFNAME.C +*/ + +#include <stdio.h> +#include <string.h> +#include <conio.h> + +#ifdef TRUE + #undef TRUE +#endif +#ifdef FALSE + #undef FALSE +#endif +#ifdef ERROR + #undef ERROR +#endif + +enum LOGICAL {ERROR = -1, SUCCESS, FALSE = 0, TRUE}; + +#if defined(__TURBOC__) + #include <dir.h> +#endif +#if !defined( MAXFILE ) + #define MAXFILE 9 +#endif + +#define NUL '\0' + +/* +** Prototypes +*/ + +int valid_fname (char *fname, int wild_check); + +/* +** valid_fname.c +** +** Verifies whether a filename is valid or invalid without +** altering the passed filename itself. +** +** Note that only filenames are validated. Path and drive specs +** need to be separately validated. See FLN_FIX.C in SNIPPETS. +** +** Arguments: 2 - fname = a char array MAXFILE long +** wild_check: 0 means wildcard use okay +** any other value means test for +** wildcards which are not acceptable +** +** Returns: ERROR - fname is invalid +** SUCCESS - fname is valid +** +** Side effects: none +** +** Speed: 1) Turbo Profiler rates valid_fname at 0.0004 sec/call +** on an Intel 80286. +** 2) Token testing from both ends to center yields a slight +** improvement. +** +** Notes: Space, ASCII character 32, is a special case. Dos will +** write a filename or volume label that includes a space. +** Getting access to that file, afterwards, is not always +** easy :) For my purposes, space is an invalid filename +** token. You? You're on your own :) +** +** Uses strnicmp() and stricmp(), non-ISO/ANSI, but available on +** all DOS C compilers (MSC, BC++, SC++ WC, etc.) +** +** Revisions: 1) Dropped str2upper after comment by David Johnson +** on 07-17-93 +** 2) Added [] to token list after comment by Ed +** Kowalski on 07-17-93 +** 3) Added lpt1-lpt3, com1-com4 and clock$ to +** invalid name list after comment by Ed +** Kowalski on 07-17-93 +** 4) Eliminated double exit points after my own +** comment to Bob Stout :) on 07/22/1993 +** 5) Revisions to detect DOS extension errors on 03/13/94 +** +** Public domain by Sid Rogers and Bob Stout +** +*/ + +int valid_fname(char *fname, int wild_check) +{ + /* invalid filename tokens */ + + static char invalid_tokens[] = "\0 ,;:|\\/<>\"+=[]*?"; + static int itoklen = sizeof(invalid_tokens) - 1; + + /* invalid file names -- even with extension .xxx */ + + static char *invalid_3lnam[]={"AUX","CON","PRN","NUL","COM",NULL}; + + /* other invalid file & directory names */ + + static char *invalid_4lnam[]={"LPT1","LPT2","LPT3","COM1", + "COM2","COM3","COM4",NULL}; + + static char *invalid_6lnam = "CLOCK$"; + + int num_toks, fl, i, j, k, proceed = 0; + char *p; + + /* Handle the critical stuff first */ + + for (i = 0; invalid_3lnam[i]; ++i) + { + if (SUCCESS == strnicmp(fname, invalid_3lnam[i], 3)) + proceed = ERROR; + } + + /* Handle extensions next */ + + if (ERROR != proceed && NULL != (p = strchr(fname, '.'))) + { + if (3 < strlen(p+1) || NULL != strchr(p+1, '.')) + proceed = ERROR; + if (8 < (p - fname)) + proceed = ERROR; + } + + if (ERROR != proceed) + { + if (p) + *p = NUL; + + for (i = 0; invalid_4lnam[i]; ++i) + { + if (SUCCESS == stricmp(fname, invalid_4lnam[i])) + proceed = ERROR; + } + + if (SUCCESS == stricmp(fname, invalid_6lnam)) + proceed = ERROR; + if (p) + *p = '.'; + else if (8 < strlen(fname)) + proceed = ERROR; + } + + fl = strlen(fname); + + /* process filename for invalid tokens */ + + if (ERROR != proceed) + { + if (wild_check) + num_toks = itoklen; /* wildcards invalid */ + else num_toks = itoklen - 2; /* wildcards ok */ + + for (i = -1, j = 0; i < 0 && j < num_toks; j++) + { + for (k = 0; k < fl; k++) + if(invalid_tokens[j] == fname[k]) + i=j; + } + if (i >= 0) + proceed = ERROR; + } + return proceed; /* single exit point */ +} + +#ifdef TEST + +/* +** Revised function test - Performs standard tests and then validates +** filenames passed on the command line. +*/ + +main(int argc, char *argv[]) +{ + static char *name_test[]= {"aaa","aux","con","prn","nul","lpt1", "lpt2", + "lpt3","com1","com2","com3", "com4","bbbb", + "clock$","com.c", "cccccc",NULL}; + + static char *token_test[]={"00fname.","01 fname","02fname,", "03fname[", + "04fname;","05fname:", "06fname|","07fname/", + "08fname<", "09fname>","10fname+","11fname=", + "12fname\\","13fname\"","14fname]", + "15fname*", "16fname?","filename", NULL}; + + char fname[MAXFILE]; + int i; + + for (i = 0; name_test[i]; ++i) + { + strcpy(fname,name_test[i]); + printf("%6s is %s\n",fname, + valid_fname(fname,0) ? "INvalid" : "Valid"); + } + + puts("\nHit a key"); + getch(); + + puts("\n[Wildcards not allowed]\n"); + for (i = 0; token_test[i]; ++i) + { + strcpy(fname,token_test[i]); + printf("%s is %s\n",fname, + valid_fname(fname,1) ? "INvalid" : "Valid"); + } + + puts("\nHit a key"); + getch(); + + puts("\n[Wildcards allowed]\n"); + for (i = 0; token_test[i]; ++i) + { + strcpy(fname,token_test[i]); + printf("%s is %s\n",fname, + valid_fname(fname,0) ? "INvalid" : "Valid"); + } + + puts("\nHit a key"); + getch(); + + while (--argc) + { + strcpy(fname, *(++argv)); + printf("%s is %s\n",fname, + valid_fname(fname,1) ? "INvalid" : "Valid"); + } + return 0; +} +#endif diff --git a/reference/C/CONTRIB/SNIP/video.c b/reference/C/CONTRIB/SNIP/video.c new file mode 100755 index 0000000..885179b --- /dev/null +++ b/reference/C/CONTRIB/SNIP/video.c @@ -0,0 +1,181 @@ +/*------------------------------[ vhdw.c ]-----------------------------*/ +/* Hardware Interface Routines */ +/*--------------------------------------------------------------------- + +/*---------------------------------------------------------------------*/ +/* This code is a subset of a library copyrighted by Jeff Dunlop. */ +/* License is hereby granted for unrestricted use. */ +/*---------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------*/ +/* dv_info: get video and version info about DesqView */ +/* get_rows: determine number of rows on screen */ +/* get_cols: determine number of columns on screen */ +/* get_vidpage: determine the current text mode video page */ +/* get_vidbase: determine the base of video ram */ +/* is_dv: determine if DesqView is loaded */ +/* is_egavga: determine if monitor is ega/vga */ +/*---------------------------------------------------------------------*/ + +/*--------------------------------------------------------------*/ +/*-----------------------[ include files ]----------------------*/ +/*--------------------------------------------------------------*/ + +#include <dos.h> + +#ifndef MK_FP + #define MK_FP(seg,offset) \ + ((void _far *)(((unsigned long)(seg)<<16) | (unsigned)(offset))) +#endif + +typedef struct +{ + int ver_major; + int ver_minor; + unsigned regen_buf; + int win_rows; + int win_cols; +} DV_INFO; + +/*------------------------[ get_vidpage ]-----------------------*/ +/* Determine the current text mode video page */ +/*--------------------------------------------------------------*/ +/* local: */ +/* regs = register storage buffer */ +/* return: */ +/* video page number as determined by bios call */ +/*--------------------------------------------------------------*/ + +unsigned char get_vidpage(void) +{ + union REGS regs; + + regs.h.ah = 0x0f; + int86(0x10, ®s, ®s); + return regs.h.bh; +} + +/*---------------------------[ is_dv ]--------------------------*/ +/* Determine whether DesqView is active */ +/*--------------------------------------------------------------*/ + +int is_dv(void) +{ + union REGS regs; + + regs.h.ah = 0x2b; + regs.x.cx = 0x4445; /* 'DE' */ + regs.x.dx = 0x5351; /* 'SQ' */ + regs.h.al = 1; /* get version */ + int86(0x21, ®s, ®s); + + return regs.h.al != 0xff; +} + +/*--------------------------[ dv_info ]-------------------------*/ +/* Return screen and version info about DesqView */ +/*--------------------------------------------------------------*/ +/* return: */ +/* -1 on error */ +/*--------------------------------------------------------------*/ + +int get_dvinfo(DV_INFO *dv_info) +{ + union REGS regs; + + regs.h.ah = 0x2b; + regs.x.cx = 0x4445; /* 'DE' */ + regs.x.dx = 0x5351; /* 'SQ' */ + regs.h.al = 1; /* get version */ + int86(0x21, ®s, ®s); + + if (regs.h.al == 0xff) + return -1; + dv_info->ver_major = regs.h.bh; + dv_info->ver_minor = regs.h.bl; + regs.h.al = 4; /* get screen info */ + int86(0x21, ®s, ®s); + + if (regs.h.al == 0xff) + return -1; + dv_info->regen_buf = regs.x.dx; + dv_info->win_rows = regs.h.bh; + dv_info->win_cols = regs.h.bl; + return 0; +} + +/*------------------------[ get_vidbase ]-----------------------*/ +/* Determine the base of video ram */ +/*--------------------------------------------------------------*/ +/* local: */ +/* regs = register union for ISR */ +/* return: */ +/* the current text base segment */ +/*--------------------------------------------------------------*/ + +unsigned get_vidbase(void) +{ + union REGS regs; + DV_INFO dv_info; + + if (is_dv() && get_dvinfo(&dv_info) != -1) + return dv_info.regen_buf; + else + { + regs.h.ah = 0xf; + int86(0x10, ®s, ®s); + + if (regs.h.al == 7) + return 0xb000; + else + return 0xb800; + } +} + +/*-------------------------[ get_rows ]-------------------------*/ +/* Determine the number of rows in current text mode screen */ +/*--------------------------------------------------------------*/ + +int is_egavga(void); + +int get_rows(void) +{ + DV_INFO dv_info; + char far *p = MK_FP(0x40, 0x84); + + if (is_dv() && get_dvinfo(&dv_info) != -1) + return dv_info.win_rows; + else + return *p + is_egavga(); +} + +/*-------------------------[ get_cols ]-------------------------*/ +/* Determine the number of columns in current text screen */ +/*--------------------------------------------------------------*/ + +int get_cols(void) +{ + DV_INFO dv_info; + int far *p = MK_FP(0x40, 0x4a); + + if (is_dv() && get_dvinfo(&dv_info) != -1) + return dv_info.win_cols; + else + return *p; +} + +/*-------------------------[ is_egavga ]------------------------*/ +/* Determine whether the current text mode is ega/vga */ +/*--------------------------------------------------------------*/ + +int is_egavga(void) +{ + union REGS regs; + + regs.h.ah = 0x1a; + regs.h.al = 0; + + int86(0x10, ®s, ®s); + + return regs.h.al == 0x1a; +} diff --git a/reference/C/CONTRIB/SNIP/vidport.c b/reference/C/CONTRIB/SNIP/vidport.c new file mode 100755 index 0000000..a3b3286 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/vidport.c @@ -0,0 +1,114 @@ +/* +** Portable PC screen functions +** Public domain by Bob Stout +** Uses SCROLL.C, also from SNIPPETS +*/ + +#include <stdio.h> +#include <dos.h> +#include "scrnmacs.h" /* Also in SNIPPETS */ + +void GotoXY(int col, int row) +{ + union REGS regs; + + setbuf(stdout, NULL); + regs.h.dh = (unsigned)row; + regs.h.dl = (unsigned)col; + regs.h.bh = VIDPAGE; + regs.h.ah = 2; + int86(0x10, ®s, ®s); +} + +void ClrScrn(int vattrib) +{ + scroll(SCROLL_UP, 0, vattrib, 0, 0, SCREENROWS, SCREENCOLS); + GotoXY(0, 0); /* Home cursor */ +} + +void GetCurPos(int *col, int *row) +{ + union REGS regs; + + regs.h.ah = 0x03; + regs.h.bh = VIDPAGE; + int86(0x10, ®s, ®s); + *row = regs.h.dh; + *col = regs.h.dl; +} + +int GetCurAtr(void) +{ + int row, col; + unsigned short chat; + + GetCurPos(&col, &row); + chat = *((unsigned FAR *)MK_FP(SCREENSEG, + (row * SCREENCOLS + col) << 1)); + return (chat >> 8); +} + +void ClrEol(void) +{ + int row, col; + + GetCurPos(&col, &row); + scroll(0, 0, GetCurAtr(), row, col, row, SCREENCOLS); +} + +void ClrEop(void) +{ + int row, col; + + GetCurPos(&col, &row); + ClrEol(); + if (++row < SCREENROWS) + scroll(0, 0, GetCurAtr(), row, 0, SCREENROWS, SCREENCOLS); +} + +void Repaint(int vattrib) +{ + unsigned short FAR *screen = SCRBUFF; + int row, col; + + for (row = 0; row < SCREENROWS; ++row) + { + for (col = 0; col < SCREENCOLS; ++col, ++screen) + *screen = (*screen & 0xff) + (vattrib << 8); + } +} + +#ifdef TEST + +#include <conio.h> + +/* +** Run this test with a screenful of misc. stuff +*/ + +main() +{ + int vatr = GetCurAtr(); + + GotoXY(1, 1); + fputs("Testing ClrEol()", stderr); + ClrEol(); + fputs("\nHit any key to continue...\n", stderr); + getch(); + fputs("Testing ClrEop()", stderr); + ClrEop(); + fputs("\nHit any key to continue...\n", stderr); + getch(); + ClrScrn(vatr); + GotoXY(0, 0); + fputs("ClrScrn() tested", stderr); + fputs("\nHit any key to continue...\n", stderr); + getch(); + Repaint(BG_(CYAN) | BLACK); + fputs("Repaint() tested", stderr); + fputs("\nHit any key to continue...\n", stderr); + getch(); + Repaint(vatr); +} + +#endif diff --git a/reference/C/CONTRIB/SNIP/vio.asm b/reference/C/CONTRIB/SNIP/vio.asm new file mode 100755 index 0000000..58ae831 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/vio.asm @@ -0,0 +1,896 @@ +; +; screen handling primitives +; +; by: jim nutt +; + +.model large + +.data + +vseg dw 0b000h +vmode db ? +x dw 0 +y dw 0 +color db 07h +ofs dw 0 +xhite db 8 + +; video information block + +VIOinfo struc + level db ? + db ? + dw ? + flags dw ? + mode db ? + db ? + colors dw ? + pixcol dw ? + pixrow dw ? + txtcol dw ? + txtrow dw ? +VIOinfo ends + +info VIOinfo <0,0,14,1,0,0,2,0,0,80,25> + +.code + +public _VIOopen, _VIOclose, _VIOcolumns, _VIOrows, _VIOmode +public _VIOscrollright, _VIOscrollleft, _VIOscrollup, _VIOscrolldown +public _VIOclear, _VIOputc, _VIOputs, _VIOgetca, _VIOgetra, _VIOheight, +public _VIOsetfore, _VIOsetback, _VIOgetfore, _VIOgetback +public _VIOgotoxy, _VIOupdate, _VIOwherex, _VIOwherey, _VIOputr +public _VIOcursor, _VIOsegment, _VIOsetSegment, _VIOsetRows, _VIOsetCols + +;int _far _pascal VIOheight(void) + +_VIOheight proc + + mov al, xhite; + xor ah,ah; + ret + +_VIOheight endp + +;int _far _pascal VIOopen(void); + +_VIOopen proc + + push ds + + mov ax,3000h ; get dos version, v4 can do this from dos + int 21h + + cmp al,4 + je odos4 + + mov ax,0f00h ; get screen mode and width + int 10h + + mov vmode, al + + cmp al,7 + je mono + + xor al,al + xchg al,ah + mov info.txtcol,ax + mov vseg,0b800h + + push di + mov ax,0fe00h + mov es,vseg + mov di,0 + int 10h + pop di + mov vseg,es + + push bp ; how many rows + mov ax,1130h + mov bh,1h + xor dx,dx + int 10h + pop bp + + cmp dl,0 + je cga + + mov xhite,cl + inc dl + xor dh,dh + mov info.txtrow,dx + +mono: mov ax,0 + pop ds + ret + +odos4: mov ax,440ch + mov bx,0 + mov cx,037fh + mov dx,offset info + int 21h + jnc l1 + pop ds + ret + +cga: mov info.txtrow,25 + +l1: mov ax,0 + pop ds + ret + +_VIOopen endp + +;void _far _pascal VIOclose(void); + +_VIOclose proc + + mov ax,3000h + int 21h + + cmp al,4 + jne l2 + + mov ax,440ch + mov bx,0 + mov cx,035fh + mov dx,offset info + int 21h + +l2: ret + +_VIOclose endp + +;int _far VIOcolumns(void); + +_VIOcolumns proc + + mov ax,info.txtcol + ret + +_VIOcolumns endp + +;int _far VIOrows(void); + +_VIOrows proc + + mov ax,info.txtrow + ret + +_VIOrows endp + +;int _far VIOmode(void); + +_VIOmode proc + + mov al,vmode + xor ah,ah + ret + +_VIOmode endp + +;int _far VIOwherex(void); + +_VIOwherex proc + + mov ax,x + ret + +_VIOwherex endp + +;int _far VIOwherey(void); + +_VIOwherey proc + + mov ax,y + ret + +_VIOwherey endp + +;void _far VIOscrollright(int x1, int y1, int x2, int y2, int count); + +_VIOscrollright proc + + push bp + mov bp,sp + pushf + + std + + push di + push si + + mov ax,[bp+8] + mov bx,[bp+12] + sub bx,ax + mov cx,info.txtcol + mul cl + mov dx,[bp+10] + add dx,ax + shl dx,1 + mov cx,[bp+10] + sub cx,[bp+6] + + add bx,2 + mov [bp+6],cx + mov [bp+8],bx + + mov es,vseg + +sr1: dec word ptr [bp+8] + jz sr3 + mov bx,[bp+14] + + push ds + mov ah,color + mov al,20h + + push es + pop ds + +sr2: mov di,dx + mov si,di + dec si + dec si + mov cx,[bp+6] + rep movsw + stosw + dec bx + jnz sr2 + + pop ds + mov ax,info.txtcol + shl ax,1 + add dx,ax + jmp sr1 + +sr3: pop si + pop di + + popf + pop bp + ret + +_VIOscrollright endp + +;void _far VIOscrollleft(int x1, int y1, int x2, int y2, int count); + +_VIOscrollleft proc + + push bp + mov bp,sp + pushf + + push di + push si + + mov ax,[bp+8] + mov bx,[bp+12] + sub bx,ax + mov cx,info.txtcol + mul cl + mov dx,[bp+6] + add dx,ax + shl dx,1 + mov cx,[bp+10] + sub cx,[bp+6] + + add bx,2 + mov [bp+6],cx + mov [bp+8],bx + + mov es,vseg + +sl1: dec word ptr [bp+8] + jz sl3 + mov bx,[bp+14] + + push ds + mov ah,color + mov al,20h + + push es + pop ds + +sl2: mov di,dx + mov si,di + inc si + inc si + mov cx,[bp+6] + rep movsw + stosw + dec bx + jnz sl2 + + pop ds + mov ax,info.txtcol + shl ax,1 + add dx,ax + jmp sl1 + +sl3: pop si + pop di + + popf + pop bp + ret + +_VIOscrollleft endp + +;void _far VIOscrollup(int x1, int y1, int x2, int y2, int count); + +_VIOscrollup proc + + push bp + mov bp,sp + push di + push si + + mov es,vseg + + mov bx,[bp+6] + mov ax,[bp+8] + mov dx,info.txtcol + mul dl + add ax,bx + shl ax,1 + shl dx,1 + + push ax + push ds + push ax + + mov cx,[bp+10] + sub cx,bx + mov bx,cx + + mov ax,[bp+12] + sub ax,[bp+8] + mov [bp+12],ax + + push es + pop ds + inc word ptr [bp+14] + +l9: dec word ptr [bp+14] + jz l11 + mov ax,[bp+12] + +l10: pop di + mov si,di + add si,dx + push si + mov cx,bx + rep movsw + dec ax + jne l10 + + pop di + pop ds + mov al,20h + mov ah,color + mov cx,bx + rep stosw + + pop di + push di + push ds + push di + + push es + pop ds + jmp l9 + +l11: pop ax + pop ds + pop ax + pop si + pop di + + pop bp + ret + +_VIOscrollup endp + +;void _far VIOscrolldown(int x1, int y1, int x2, int y2, int count); + +_VIOscrolldown proc + + push bp + mov bp,sp + push di + push si + + mov es,vseg + + mov bx,[bp+6] + mov ax,[bp+12] + mov dx,info.txtcol + mul dl + add ax,bx + shl ax,1 + shl dx,1 + + push ax + push ds + push ax + + mov cx,[bp+10] + sub cx,bx + mov bx,cx + + mov ax,[bp+12] + sub ax,[bp+8] + mov [bp+12],ax + + push es + pop ds + inc word ptr [bp+14] + +l6: dec word ptr [bp+14] + jz l7 + mov ax,[bp+12] + +l8: pop di + mov si,di + sub si,dx + push si + mov cx,bx + rep movsw + dec ax + jne l8 + + pop di + pop ds + mov al,20h + mov ah,color + mov cx,bx + rep stosw + + pop di + push di + push ds + push di + + push es + pop ds + jmp l6 + +l7: pop ax + pop ds + pop ax + pop si + pop di + pop bp + ret + +_VIOscrolldown endp + +;void _far VIOclear(int x1, int y1, int x2, int y2); + +_VIOclear proc + + push bp + mov bp,sp + push di + push si + + mov es,vseg + + mov ax,[bp+8] + mov bx,[bp+6] + mov cx,info.txtcol + mul cl + add ax,bx + shl ax,1 + mov si,ax + mov bx,[bp+10] + sub bx,[bp+6] + inc bx + mov dx,[bp+12] + sub dx,[bp+8] + inc dx + mov al,20h + mov ah,color + +l5: mov di,si + mov cx,bx + rep stosw + mov cx,info.txtcol + shl cx,1 + add si,cx + dec dx + jne l5 + + pop si + pop di + pop bp + ret + +_VIOclear endp + +;void _far VIOputc(const char c); + +_VIOputc proc + + push bp + mov bp,sp + push di + + mov es,vseg + mov di,ofs + + mov ax,[bp+6] + mov ah,color + + stosw + + mov ofs,di + pop di + + mov ax,x + inc ax + cmp ax,info.txtcol + jge cwrap + + mov x,ax + + pop bp + ret + +cwrap: inc y + sub ax,info.txtcol + mov x,ax + + pop bp + ret + +_VIOputc endp + +;void _far VIOputs(const char far * s); + +_VIOputs proc + + push bp + mov bp,sp + push di + push si + push ds + + mov es,vseg + mov di,ofs + + mov ah,color + lds si,[bp+6] + mov bx,x + +l3: lodsb + cmp al,0 + je l4 + stosw + inc bx + + jmp l3 + +l4: mov ofs,di + pop ds + pop si + pop di + + cmp bx,info.txtcol + jge swrap + + mov x,bx + + pop bp + ret + +swrap: inc y + sub bx,info.txtcol + mov x,bx + + pop bp + ret + +_VIOputs endp + +;int _far VIOgetca(const int x, const int y); + +_VIOgetca proc + + push bp + mov bp,sp + + mov es,vseg + mov ax,[bp+8] + mov bx,[bp+6] + mov cx,info.txtcol + mul cl + add ax,bx + shl ax,1 + + xchg ax,bx + mov ax,es:[bx] + + pop bp + ret + +_VIOgetca endp + +;int *_far VIOgetra(int x1, int y1, int x2, int y2, int * b); + +_VIOgetra proc + + push bp + mov bp,sp + push di + push si + push ds + + mov ax,[bp+8] ; y1 + mov bx,info.txtcol + mul bl ; y1 * width of screen + add ax,[bp+6] + shl ax,1 ; x1 * 2 + shl bx,1 ; width * 2 + mov cx,[bp+10] + sub cx,[bp+6] ; x2 - x1 + mov dx,[bp+12] + sub dx,[bp+8] ; y2 - y1 + inc dx + inc cx + les di,[bp+14] + mov ds,vseg + push cx + +gr1: pop cx + push cx + mov si,ax + rep movsw + add ax,bx + dec dx + jnz gr1 + + pop cx + + pop ds + pop si + pop di + pop bp + ret + +_VIOgetra endp + +;void _far VIOputr(int x, int y, int w, int h, int far * b); + +_VIOputr proc + + push bp + mov bp,sp + + push ds + push si + push di + + mov ax,[bp+8] + mov bx,info.txtcol + mul bl ; y * width + add ax,[bp+6] + shl ax,1 + shl bx,1 + + mov es,vseg + + lds si,[bp+14] + mov dx,[bp+10] + +pr1: mov cx,dx + mov di,ax + rep movsw + add ax,bx + dec word ptr [bp+12] + jnz pr1 + + pop di + pop si + pop ds + + pop bp + ret + +_VIOputr endp + +;void _far VIOsetfore(const int c); + +_VIOsetfore proc + + push bp + mov bp,sp + + mov bl,color + and bx,00f0h + mov ax,[bp+6] + and ax,000fh + or ax,bx + mov color,al + + pop bp + ret + +_VIOsetfore endp + +;void _far VIOsetback(const int c); + +_VIOsetback proc + + push bp + mov bp,sp + + mov bl,color + and bx,000fh + mov ax,[bp+6] + and ax,000fh + shl ax,1 + shl ax,1 + shl ax,1 + shl ax,1 + or ax,bx + mov color,al + + pop bp + ret + +_VIOsetback endp + +;int _far VIOgetfore(void); + +_VIOgetfore proc + + mov al,color + and ax,000fh + ret + +_VIOgetfore endp + +;int _far VIOgetback(void); + +_VIOgetback proc + + mov al,color + and ax,00f0h + shr al,1 + shr al,1 + shr al,1 + shr al,1 + ret + +_VIOgetback endp + +;void _far VIOgotoxy(int x, int y); + +_VIOgotoxy proc + + push bp + mov bp,sp + + mov bx,[bp + 6] + mov ax,[bp + 8] + + mov x,bx + mov y,ax + + mov cx,info.txtcol + mul cl + + add ax,bx + shl ax,1 + + mov ofs,ax + + pop bp + ret + +_VIOgotoxy endp + +;void _far VIOupdate(int x1, int y1, int x2, int y2); + +_VIOupdate proc + + mov ah,2 + mov bh,0 + mov cx,y + mov dx,x + mov dh,cl + int 10h + + ret + +_VIOupdate endp + +;void _far VIOcursor(int _far * x, int _far * y, int _far * shape); + +_VIOcursor proc + + push bp + mov bp,sp + push ds + + mov ah,3 + mov bh,0 + int 10h + + mov al,dl + cbw + lds bx,[bp + 6] + mov [bx],ax + + mov al,dh + cbw + lds bx,[bp + 10] + mov [bx],ax + + lds bx,[bp + 14] + mov [bx],cx + + pop ds + pop bp + ret + +_VIOcursor endp + +;unsigned int _far VIOsegment(void); + +_VIOsegment proc + + mov ax, vseg + ret + +_VIOsegment endp + +;void _far VIOsetSegment(unsigned int s); + +_VIOsetSegment proc + + push bp + mov bp,sp + + mov ax, [bp + 6] + mov vseg,ax + + pop bp + ret + +_VIOsetSegment endp + +;void _far VIOsetRows(int r); + +_VIOsetRows proc + + push bp + mov bp,sp + + mov ax,[bp + 6] + mov info.txtrow,ax + + pop bp + ret + +_VIOsetRows endp + +;void _far VIOsetCols(int c); + +_VIOsetCols proc + + push bp + mov bp,sp + + mov ax,[bp + 6] + mov info.txtcol, ax + + pop bp + ret + +_VIOsetCols endp + +end diff --git a/reference/C/CONTRIB/SNIP/vio.h b/reference/C/CONTRIB/SNIP/vio.h new file mode 100755 index 0000000..f199208 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/vio.h @@ -0,0 +1,90 @@ +/* +** By: Jim Nutt +*/ + +#ifndef VIO_H +#define VIO_H + +#if __cplusplus +extern "C" { +#endif + +#if defined(__TURBOC__) + #define _far far + #define _pascal pascal +#endif + +/* initialization and termination functions */ + +int _far VIOopen(void); +void _far VIOclose(void); + +/* scrolling functions */ + +void _far VIOscrollright(int x1, int y1, int x2, int y2, int count); +void _far VIOscrollleft(int x1, int y1, int x2, int y2, int count); +void _far VIOscrollup(int x1, int y1, int x2, int y2, int count); +void _far VIOscrolldown(int x1, int y1, int x2, int y2, int count); + +/* screen clear */ + +void _far VIOclear(int x1, int y1, int x2, int y2); + +/* write to screen */ + +void _far VIOputc(const char c); +void _far VIOputs(const char far * s); +void _far VIOputr(int x, int y, int w, int h, int _far * b); + +/* read from screen */ + +int _far VIOgetca(const int x, const int y); +int _far * _far VIOgetra(int x1, int y1, int x2, int y2, int _far * b); + +/* set colors */ + +void _far VIOsetfore(const int c); +void _far VIOsetback(const int c); + +/* get current color settings */ + +int _far VIOgetfore(void); +int _far VIOgetback(void); + +/* set the write cursor */ + +void _far VIOgotoxy(int x, int y); + +/* update the screen and visible cursor */ + +void _far VIOupdate(); + +/* get the current write cursor position */ + +int _far VIOwherex(void); +int _far VIOwherey(void); + +/* get screen information */ + +unsigned int _far VIOsegment(void); + +int _far VIOcolumns(void); +int _far VIOrows(void); +int _far VIOmode(void); +int _far VIOheight(void); + +/* set segment information */ + +void _far VIOsetSegment(unsigned int s); +void _far VIOsetRows(int r); +void _far VIOsetCols(int c); + +/* get BIOS cursor location */ + +void _far VIOcursor(int _far * x, int _far * y, int _far * shape); + +#if __cplusplus +} ; +#endif + +#endif diff --git a/reference/C/CONTRIB/SNIP/vt100.txt b/reference/C/CONTRIB/SNIP/vt100.txt new file mode 100755 index 0000000..6cd5f59 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/vt100.txt @@ -0,0 +1,199 @@ +# +# VT100 Escape Codes +# symbology: +# ^[ = escape character (ascii 27 decimal) +# <v> = single or double digit number. Vertical coordinate +# <h> = single or double digit number. Horizontal coordinate +# <n> = single or double digit number. Number of chars/lines +# others = single characters just as they appear. +# +# NOTE: Many sequences have "^[[" which is two chars: "escape" and "[". +# + +Name Description Esc Code +-------------------- ------------------------------------- ----------- +setnl LMN Set new line mode ^[[20h +setappl DECCKM Set cursor key to application ^[[?1h +setansi DECANM Set ANSI (versus VT52) none +setcol DECCOLM Set number of columns to 132 ^[[?3h +setsmooth DECSCLM Set smooth scrolling ^[[?4h +setrevscrn DECSCNM Set reverse video on screen ^[[?5h +setorgrel DECOM Set origin to relative ^[[?6h +setwrap DECAWM Set auto-wrap mode ^[[?7h +setrep DECARM Set auto-repeat mode ^[[?8h +setinter DECINLM Set interlacing mode ^[[?9h + +setlf LMN Set line feed mode ^[[20l +setcursor DECCKM Set cursor key to cursor ^[[?1l +setvt52 DECANM Set VT52 (versus ANSI) ^[[?2l +resetcol DECCOLM Set number of columns to 80 ^[[?3l +setjump DECSCLM Set jump scrolling ^[[?4l +setnormscrn DECSCNM Set normal video on screen ^[[?5l +setorgabs DECOM Set origin to absolute ^[[?6l +resetwrap DECAWM Reset auto-wrap mode ^[[?7l +resetrep DECARM Reset auto-repeat mode ^[[?8l +resetinter DECINLM Reset interlacing mode ^[[?9l + +altkeypad DECKPAM Set alternate keypad mode ^[= +numkeypad DECKPNM Set numeric keypad mode ^[> + +setukg0 Set United Kingdom G0 character set ^[(A +setukg1 Set United Kingdom G1 character set ^[)A +setusg0 Set United States G0 character set ^[(B +setusg1 Set United States G1 character set ^[)B +setspecg0 Set G0 special chars. & line set ^[(0 +setspecg1 Set G1 special chars. & line set ^[)0 +setaltg0 Set G0 alternate character ROM ^[(1 +setaltg1 Set G1 alternate character ROM ^[)1 +setaltspecg0 Set G0 alt char ROM and spec. graphics ^[(2 +setaltspecg1 Set G1 alt char ROM and spec. graphics ^[)2 + +setss2 SS2 Set single shift 2 ^[N +setss3 SS3 Set single shift 3 ^[O + +modesoff SGR0 Turn off character attributes ^[[m +modesoff SGR0 Turn off character attributes ^[[0m +bold SGR1 Turn bold mode on ^[[1m +lowint SGR2 Turn low intensity mode on ^[[2m +underline SGR4 Turn underline mode on ^[[4m +blink SGR5 Turn blinking mode on ^[[5m +reverse SGR7 Turn reverse video on ^[[7m +invisible SGR8 Turn invisible text mode on ^[[8m + +setwin DECSTBM Set top and bottom line#s of a window ^[[<v>;<v>r + +cursorup(n) CUU Move cursor up n lines ^[[<n>A +cursordn(n) CUD Move cursor down n lines ^[[<n>B +cursorrt(n) CUF Move cursor right n lines ^[[<n>C +cursorlf(n) CUB Move cursor left n lines ^[[<n>D +cursorhome Move cursor to upper left corner ^[[H +cursorhome Move cursor to upper left corner ^[[;H +cursorpos(v,h) CUP Move cursor to screen location v,h ^[[<v>;<h>H +hvhome Move cursor to upper left corner ^[[f +hvhome Move cursor to upper left corner ^[[;f +hvpos(v,h) CUP Move cursor to screen location v,h ^[[<v>;<h>f +index IND Move/scroll window up one line ^[D +revindex RI Move/scroll window down one line ^[M +nextline NEL Move to next line ^[E +savecursor DECSC Save cursor position and attributes ^[7 +restorecursor DECSC Restore cursor position and attributes ^[8 + +tabset HTS Set a tab at the current column ^[H +tabclr TBC Clear a tab at the current column ^[[g +tabclr TBC Clear a tab at the current column ^[[0g +tabclrall TBC Clear all tabs ^[[3g + +dhtop DECDHL Double-height letters, top half ^[#3 +dhbot DECDHL Double-height letters, bottom half ^[#4 +swsh DECSWL Single width, single height letters ^[#5 +dwsh DECDWL Double width, single height letters ^[#6 + +cleareol EL0 Clear line from cursor right ^[[K +cleareol EL0 Clear line from cursor right ^[[0K +clearbol EL1 Clear line from cursor left ^[[1K +clearline EL2 Clear entire line ^[[2K + +cleareos ED0 Clear screen from cursor down ^[[J +cleareos ED0 Clear screen from cursor down ^[[0J +clearbos ED1 Clear screen from cursor up ^[[1J +clearscreen ED2 Clear entire screen ^[[2J + +devstat DSR Device status report ^[5n +termok DSR Response: terminal is OK ^[0n +termnok DSR Response: terminal is not OK ^[3n + +getcursor DSR Get cursor position ^[6n +cursorpos CPR Response: cursor is at v,h ^[<v>;<h>R + +ident DA Identify what terminal type ^[[c +ident DA Identify what terminal type (another) ^[[0c +gettype DA Response: terminal type code n ^[[?1;<n>0c + +reset RIS Reset terminal to initial state ^[c + +align DECALN Screen alignment display ^[#8 +testpu DECTST Confidence power up test ^[[2;1y +testlb DECTST Confidence loopback test ^[[2;2y +testpurep DECTST Repeat power up test ^[[2;9y +testlbrep DECTST Repeat loopback test ^[[2;10y + +ledsoff DECLL0 Turn off all four leds ^[[0q +led1 DECLL1 Turn on LED #1 ^[[1q +led2 DECLL2 Turn on LED #2 ^[[2q +led3 DECLL3 Turn on LED #3 ^[[3q +led4 DECLL4 Turn on LED #4 ^[[4q + +# +# All codes below are for use in VT52 compatibility mode. +# + +setansi Enter/exit ANSI mode (VT52) ^[< + +altkeypad Enter alternate keypad mode ^[= +numkeypad Exit alternate keypad mode ^[> + +setgr Use special graphics character set ^[F +resetgr Use normal US/UK character set ^[G + +cursorup Move cursor up one line ^[A +cursordn Move cursor down one line ^[B +cursorrt Move cursor right one char ^[C +cursorlf Move cursor left one char ^[D +cursorhome Move cursor to upper left corner ^[H +cursorpos(v,h) Move cursor to v,h location ^[<v><h> +revindex Generate a reverse line-feed ^[I + +cleareol Erase to end of current line ^[K +cleareos Erase to end of screen ^[J + +ident Identify what the terminal is ^[Z +identresp Correct response to ident ^[/Z + +#======================================================================= + +# +# VT100 Special Key Codes +# +# These are sent from the terminal back to the computer when the +# particular key is pressed. Note that the numeric keypad keys +# send different codes in numeric mode than in alternate mode. +# See escape codes above to change keypad mode. +# + +# Function Keys: + +PF1 ^[OP +PF2 ^[OQ +PF3 ^[OR +PF4 ^[OS + + +# Arrow Keys: + Reset Set + ----- --- +up ^[A ^[OA +down ^[B ^[OB +right ^[C ^[OC +left ^[D ^[OD + + +# Numeric Keypad Keys: + + Keypad Mode + ----------------- +Keypad Key Numeric Alternate +---------- ------- --------- +0 0 ^[Op +1 1 ^[Oq +2 2 ^[Or +3 3 ^[Os +4 4 ^[Ot +5 5 ^[Ou +6 6 ^[Ov +7 7 ^[Ow +8 8 ^[Ox +9 9 ^[Oy +- (minus) - ^[Om +, (comma) , ^[Ol +. (period) . ^[On +ENTER ^M ^[OM diff --git a/reference/C/CONTRIB/SNIP/w_wrap.c b/reference/C/CONTRIB/SNIP/w_wrap.c new file mode 100755 index 0000000..e09b32b --- /dev/null +++ b/reference/C/CONTRIB/SNIP/w_wrap.c @@ -0,0 +1,139 @@ +/* w_wrap.c */ + +/* +** This is an attempt at a useful word-wrap function. It is given an array +** of characters ( a string ) and it modifies the string, replacing any +** new-lines found with spaces and placing new-lines where needed to make +** lines of the width specified, placing them only where there was previously +** white-space. ( ie. Words are not split across lines. ) At the present +** time it is rather stupid. 1) It doesn't know enough to split a line at an +** existing hyphen. 2) It has no clue about how to hyphenate words. 3) It +** makes no attempt at dealing intelligently with a singly word longer than +** the specified line length 4) It does not deal intelligently with multiple +** spaces new-lines, etc. ( eg. has no clue of paragraph seperation, etc. ) +** OTOH, it does deal well with unformatted, left justified text. +** +** Tabs will be considered the size specified. Note that word_wrap() does +** not actually expand tabs. This is only to inform it of the number of +** spaces the output device will expand them to, so it will know how much +** they expand a line. The only time word_wrap does anything with tabs, is +** if the tab size is set to zero, in which case each tab is replaced with a +** single space character. This often provides the most useful output, since +** tabs will often be in the wrong places after re-formatting, and is +** therfore the default. +** +** +** Publicly available contents: +** +** char *word_wrap(char *string,long line_len); +** Does the actual word-wrapping, as described above; +** Parameters: +** string: actual string to work with +** line_len: length of lines for output +** Returns: pointer to justified string. +** +** void set_tab_size(int size); +** Set the number of spaces that tabs will be expanded to on output +** default tab size is zero. (each tab replaced with a space char ) +** word_wrap does not actually expand tabs. This only lets it keep +** track of how many spaces they take up. If this is set to +** zero, each tab will be replaced with a single space. +** +** Other procedures: +** int get_word(char *string); +** returns the number of characters in the next word in string, +** including leading white-space characters. +** +** This compiles without warnings and runs with the following compilers: +** MS Quick C 2.51: +** Borland C++ 2.0: either as C or C++ +** GNU C++ 1.39, DOS port: either as C or C++ +** As far as I know, it uses only portable, standard C constructs. It should +** compile and run with little or no modification under nearly any C compiler +** and environment. +** +** +** This code was written Nov 16, 1991 by Jerry Coffin. +** It is hereby placed in the public domain, for free use by any and +** all who wish to do so, for any use, public, private, or commercial. +*/ + +#include <stddef.h> +#include <ctype.h> + +enum {FALSE,TRUE}; + +static int tab_size = 0; /* size to consider tabs as */ + +static size_t get_word(char *string); /* returns size of next word*/ + +void set_tab_size(size_t size) +{ + tab_size = size; +} + +char *word_wrap(char *string, size_t line_len) +{ + size_t len, /* length of current word */ + current_len = 0; /* current length of line */ + size_t start_line = 0; /* index of beginning if line */ + + while (0 != (len = get_word(&string[current_len + start_line]))) + { + if (current_len + len < line_len) + current_len += len; + else + { + string[start_line+current_len] = '\n'; + start_line += current_len + 1; + current_len = 0; + } + } + return string; +} + +static size_t get_word(char *string) +{ + register int i = 0, word_len = 0; + + if (!string[0]) + return 0; + while (isspace(string[i])) + { + if ('\t' == string[i]) + { + if (0 == tab_size) + string[i] = ' '; + else word_len += tab_size-1; + } + else if ('\n' == string[i]) + string[i]=' '; + word_len++; + i++; + } + while (string[i] && !isspace(string[i++])) + word_len++; + return word_len; +} + +#ifdef TEST + +#include <stdio.h> +#include "w_wrap.h" + +void main(void) +{ + char *string = + "This is a long line\nto be wrapped by the w_wrap function. " + "Hopefully, things will work correctly and it will be wrapped " + "between words. On the other hand, maybe I should hope that it " + "doesn't work well so I will have an opportunity\nto learn more " + "about what I'm doing"; + + printf("Here's a string wrapped to 40 columns:\n\n%s\n\n", + word_wrap(string, 40)); + printf("And here it's wrapped to 72:\n\n%s\n\n", + word_wrap(string,72)); +} + +#endif diff --git a/reference/C/CONTRIB/SNIP/w_wrap.h b/reference/C/CONTRIB/SNIP/w_wrap.h new file mode 100755 index 0000000..c05a2d5 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/w_wrap.h @@ -0,0 +1,5 @@ +/* w_wrap.h */ +/* prototypes for the functions in w_wrap.c */ + +char *word_wrap(char *string, size_t line_len); +void set_tab_size(size_t size); diff --git a/reference/C/CONTRIB/SNIP/wb_fcopy.c b/reference/C/CONTRIB/SNIP/wb_fcopy.c new file mode 100755 index 0000000..ab39cad --- /dev/null +++ b/reference/C/CONTRIB/SNIP/wb_fcopy.c @@ -0,0 +1,86 @@ +/* +** by: Walter Bright via Usenet C newsgroup +** +** modified by: Bob Stout based on a recommendation by Ray Gardner +** +** modified by: David Gersic to deal with binary files +** +** There is no point in going to asm to get high speed file copies. Since it +** is inherently disk-bound, there is no sense (unless tiny code size is +** the goal). Here's a C version that you'll find is as fast as any asm code +** for files larger than a few bytes (the trick is to use large disk buffers): +** +** To compile file_copy(), define Afilecopy=1 on the command line +** To compile file_append(), define Afileappe=1 on the command line +*/ + +#include <stdlib.h> +#include <io.h> +#include <fcntl.h> + +#if !defined(__ZTC__) && !defined(__TURBOC__) + #include <sys\types.h> +#endif + +#include <sys\stat.h> + +#if Afilecopy + int file_copy(char *from, char *to) +#else + int file_append(char *from, char *to) +#endif +{ + int fdfrom,fdto; + int bufsiz; + + fdfrom = open(from,O_RDONLY|O_BINARY,0); + if (fdfrom < 0) + return 1; +#if Afileappe + + /* Open R/W by owner, R by everyone else */ + + fdto=open(to,O_BINARY|O_CREAT|O_APPEND|O_RDWR,S_IREAD|S_IWRITE); + if (fdto < 0) + goto err; +#else + fdto=open(to,O_BINARY|O_CREAT|O_TRUNC|O_RDWR,S_IREAD|S_IWRITE); + if (fdto < 0) + goto err; +#endif + + /* Use the largest buffer we can get */ + + for (bufsiz = 0x4000; bufsiz >= 128; bufsiz >>= 1) + { + register char *buffer; + + buffer = (char *) malloc(bufsiz); + if (buffer) + { + while (1) + { + register int n; + + n = read(fdfrom,buffer,bufsiz); + if (n == -1) /* if error */ + break; + if (n == 0) /* if end of file */ + { + free(buffer); + close(fdto); + close(fdfrom); + return 0; /* success */ + } + if (n != write(fdto,buffer,(unsigned) n)) + break; + } + free(buffer); + break; + } + } +err2: close(fdto); + remove(to); /* delete any partial file */ +err: close(fdfrom); + return 1; +} diff --git a/reference/C/CONTRIB/SNIP/wc.c b/reference/C/CONTRIB/SNIP/wc.c new file mode 100755 index 0000000..62bc276 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/wc.c @@ -0,0 +1,66 @@ +/* + File wc.c - a sample word count program + Written and submitted to public domain by Jay Elkes + April, 1992 +*/ + +#include <stdio.h> +#include <string.h> +#include <ctype.h> + +int main (int argc, char *argv[]) +{ + FILE *infileptr; + char infile[80]; + + long int nl = 0; + long int nc = 0; + long int nw = 0; + + int state = 0; + const int NEWLINE = '\n'; + int c; + +/* The program name itself is the first command line arguement so we + ignore it (argv[0]) when showing user entered parameters. */ + + switch (argc - 1) + { + case (0): + printf("no parameters\n"); + return 12; + case (1): + break; + default: + printf("too many parameters\n"); + return 12; + } + + strcpy(infile,argv[1]); + + infileptr = fopen(infile,"rb"); + if (infileptr == NULL) + { + printf("Cannot open %s\n",infile); + return 12; + } + + while ((c = getc(infileptr)) != EOF) + { + ++nc; + if (c == NEWLINE) + ++nl; + if (isspace(c)) + state = 0; + else if (state == 0) + { + state = 1; + ++nw; + } + } + + /* Final Housekeeping */ + + printf("%ld Lines, %ld Words, %ld Characters", nl, nw, nc); + return 0; +} diff --git a/reference/C/CONTRIB/SNIP/weird.c b/reference/C/CONTRIB/SNIP/weird.c new file mode 100755 index 0000000..2934350 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/weird.c @@ -0,0 +1,13 @@ +#include<stdio.h> + +char *c[] = { "ENTER", "NEW", "POINT", "FIRST" }; +char **cp[] = { c+3, c+2, c+1, c }; +char ***cpp = cp; + +void main() +{ + printf("%s", **++cpp); + printf("%s ", *--*++cpp+3); + printf("%s", *cpp[-2]+3); + printf("%s\n", cpp[-1][-1]+1); +} diff --git a/reference/C/CONTRIB/SNIP/where.c b/reference/C/CONTRIB/SNIP/where.c new file mode 100755 index 0000000..d6ffdc4 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/where.c @@ -0,0 +1,132 @@ +/* +** WHERE.C: will search all DIRs on the given drive for specified file. +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <dos.h> +#include <conio.h> +#include <string.h> + +#if defined(__ZTC__) + #include <direct.h> + #define GetDrive(d) dos_getdrive(&d) + #define SetDrive(d) {unsigned x;dos_setdrive(d,&x);} + #define FAR _far +#elif defined(__TURBOC__) + #include <dir.h> + #define GetDrive(d) ((d) = getdisk() + 1) + #define SetDrive(d) (setdisk(d - 1)) + #define FAR far + #define _dos_findfirst(f,a,b) findfirst(f,b,a) + #define _dos_findnext(b) findnext(b) + #define find_t ffblk + #define _A_SUBDIR FA_DIREC + #define attrib ff_attrib + #define name ff_name +#else /* assume MSC */ + #include <direct.h> + #define GetDrive(d) _dos_getdrive(&d) + #define SetDrive(d) {unsigned x;_dos_setdrive(d,&x);} + #define FAR _far +#endif + +int count=0; + +main(int argc, char *argv[]) +{ + char *curdir, + sought[80], + *temp; + int curdrive, newdrive, p; + void searchdir(char *dir, char *ptrn); + + /* Find out where we are */ + + curdir=getcwd(NULL,80); + GetDrive(curdrive); + + /* Find out what we're looking for */ + + if(argc>1) + strcpy(sought,argv[1]); + else + { + printf("\n\nPattern to search for: "); + gets(sought); + } + + /* Get designator for another drive if specified */ + + if(sought[1]==':') + { + newdrive=(toupper(sought[0]))-64; /* convert */ + SetDrive(newdrive); + p = (sought[2]=='\\') ? 3:2; + strcpy(sought, &(sought[p])); + } + + /* Add wildcard prefix/suffix if necessary */ + + if(sought[0]=='.') + { + temp=strcat("*",sought); /* set prefix */ + strcpy(sought,temp); + } + if(!strchr(sought,'.')) + strcpy(sought,"*.*"); /* set suffix */ + + /* Perform search for pattern starting in root */ + + searchdir("\\",sought); + printf("\nNumber of matches: %d",count); + + /* Restore Original Drive and Directory */ + + SetDrive(curdrive); + chdir(curdir); + return EXIT_SUCCESS; +} + +/*------------------------------------------------------------------------- */ + +void searchdir(char *path, char *ptrn) +#define ANYFILE 0xFF /* recursive routine */ +{ + struct find_t *f; + char *wholepath; + unsigned rtn; + + chdir(path); /* change to new path */ + wholepath=getcwd(NULL,80); /* get full path name */ + f=malloc(sizeof(*f)); + + /* Search for filename matches in this directory */ + + rtn= _dos_findfirst(ptrn,ANYFILE,f); + while(rtn==0) + { + if( f->attrib != _A_SUBDIR ) + printf("%s\\%s\n",wholepath,f->name); + else printf("%s\\%s <DIR>\n",wholepath, f->name); + ++count; + + rtn = _dos_findnext(f); /* find next match */ + } /* end while loop */ + + /* Now search any subdirectories under this directory */ + + rtn= _dos_findfirst("*.*", _A_SUBDIR,f); + while(rtn==0) + { + if( (f->attrib == _A_SUBDIR) && (f->name[0] != '.')) + { + searchdir(f->name,ptrn); /* recursive call */ + chdir(wholepath); + } + rtn = _dos_findnext(f); /* search next dir */ + } + + free(wholepath); + free(f); +} diff --git a/reference/C/CONTRIB/SNIP/which_c.txt b/reference/C/CONTRIB/SNIP/which_c.txt new file mode 100755 index 0000000..a65272d --- /dev/null +++ b/reference/C/CONTRIB/SNIP/which_c.txt @@ -0,0 +1,283 @@ +Q: Which PC C/C++ compiler is best and what should I buy? + +A: This is perhaps the commonest of Frequently Asked Questions (FAQ's), +especially by beginning C'er. The honest answer is that there is no "best" +compiler and what may be best for you depends to a large degree on what +you'll be using it for. The PC C/C++ compiler market is quite brutal and the +companies that have survived have done so because some number of people think +each of them makes the "best" compiler. + + With the preceding caveat in mind, following are some summaries of the +current crop of C/C++ compilers with some of their strengths and weaknesses. +Additional recommended reading are the C/C++ compiler reviews appearing in PC +Magazine. PC Mag's reviews for many years were highly slanted and suspect, +but in the past 2 years, have become commendably objective and even-handed. + + +MIX POWER C +----------- + +Power C is the least expensive PC C compiler on the market. The compiler +itself is $20, and an additional $30 will buy their source-level debugger +along with the complete library source code with an assembler. + +So, what's the catch? + +None, actually. Power C is a quite decent and ANSI-conforming compiler which +compiles relatively tight, fast code relatively quickly. It's biggest +drawback is its use of a non-standard object file format which obviates +object-level compatibility with any other compiler using Microsoft/Intel +standard object file formats. Another problem is lack of support from 3rd +party library vendors. Although Mix sells a wide range of libraries +themselves, it's difficult to convince a vendor to produce a $100 add-on +library for a $20 compiler. + +On the plus side, Power C comes with the best user's manual for students in +the business. The beginner's tutorial section has enabled many beginning C +programmers to get up to speed without spending another dime on any other +textbooks. Should you want more instruction, Mix sells a package including +Power C with the library source and debugger along with the book "Master C" +for only $60. + +Power C's primary technical claim to fame is its floating point which +challenges the industry leader, Watcom, in many cases. It's also the only +remaining C compiler which can run effectively on small or older machines +without extended memory (SC++ can also, but is limited to *very* small +programs). + + + +MICROSOFT VISUAL C++ (VC++) +--------------------------- + +Microsoft's professional compiler now comes in two versions with the same +name. The profession version replaces Microsoft C/C++, version 7.0. The +regular version replaces Microsoft Quick C for Windows. The primary +difference is the price and the extras since each requires at least a 386 +processor, 4 Mb of *available* extended memory, and a DPMI server such as +Windows 3.1. If you don't have the machine resources, you can't use VC++. + +On the plus side, VC++ is an excellent C++ compiler and generates executables +which may not always be smaller than Borland, but usually execute faster. +Microsoft's C compilers are still the standard for PC C compilers and it +shows in the ready availability of 3rd party libraries supporting it. Support +for Windows programming is excellent with tools only rivaled by SC++ (which is +shipped with licensed copies of VC++'s MFC 2.0 class library). + +Compile times with full optimization are still quite sluggish, but using the +quick compile option can be provide acceptable results. + + +BORLAND C++ (BC++) +------------------ + +BC++ carries on Borland's tradition of providing excellent bang for the buck. +The latest release (3.1) of their professional compiler is an attractive +alternative to shops also considering VC++. BC++ isn't as demanding as VC++ +and only requires a 286 and 2 Mb of *available* extended memory to run. A full +32-bit version is currently available for OS/2 2.1. Windows programming +support is also quite good, but has been leapfrogged somewhat by VC++ and SC++ +for the time being. + +Borland's tools are uniformly excellent, but the compiler still suffers a bit +in comparison to the industry's technological leaders, Microsoft, Watcom, and +Symantec - although the gap is closing. As with VC++, it's an excellent C++ +compiler and enjoys widespread support among 3rd party library vendors. Like +all Borland compilers, ease of use was a design priority, all oriented to the +excellent IDE. + +Borland recently alienated many of their loyal customers with the release of +BC++ 4.0. In addition to the normal version x.0 bugs that we all expect, the +new version came with no DOS IDE, vastly slower compilation times (with no +apparent increase in optimization to justify the slowdown), and an odious new +license agreement that their lawyers quickly rescinded in the face of the +massive desertion of corporate clients. They're working hard to get folks to +like them again, but for the first time in their corporate life, they have +seriously dissatisfied customers and aren't quite sure how to handle it. + + +TURBO C++ (TC++) +---------------- + +TC++ is to Borland's C++ compiler targeted at the hobbyist market. The latest +version (TC++ 3.1) raised quite a stir when Borland released it requiring at +least a 286 processor and 1 Mb of *available* extended memory above the +normal 640K DOS limit. Many hobbyists running on older XT's, or machines +without the excess memory capacity have therefore failed to upgrade to the +new release. + +If you have the machine to support it, TC++ has the usual Borland attributes +of extreme ease-of-use, attractive Integrated Development Environment (IDE), +and good supporting tools. Based on the facts of BC++ 4.0 cited above, it has +become the compiler of choice for many Borland loyalists. + + +SYMANTEC C++ (SC++) +------------------- + +Symantec C++ (nee Zortech C++) was the industry's first C++ compiler, but fell +behind in tracking the C++ language spec. Bought out by Symantec in 1991, the +C compiler was always excellent and now its C++ compiler rates among the best. + +SC++ supports DOS, Mac, Unix, Win32s, and NT (OS/2 was supported in previous +Zortech releases and may be again) using an extremely powerful new object- +oriented Windows-hosted IDE. It includes excellent libraries and add-ons +including a TSR library, swapping spawn functions, a royalty-free 32-bit DOS +extender, and an excellent set of ancillary C and C++ tools libraries +including MFC 2.0 as previously noted. VC++ can generate true 32-bit code and +has a switch for generating Pentium code. At the same time that Symantec +bought Zortech, they also bought Multiscope, whose debuggers are included in +the package. As with VC++, SC++ includes excellent tools for quickly +developing Windows applications. + +SC++ has always been in the forefront of optimizer technology along with +Microsoft and Watcom. A major feature is full IEEE-754 and NCEG (Numerical C +Extensions Group (an ANSI working committee trying to make C a suitable +replacement for FORTRAN) compatibilty. + +The only negative for the current release is a poor reputation which arose +largely during the period following the Symantec acquisition of Zortech. With +6.1, these now appear mostly fixed. With the 6.1 release, support of DOS +graphics has been dropped, but an updated version of the excellent Flash +Graphics package shipped with the Zortech versions is available from FlashTek, +which also supplies improved verions of the 32-bit DOS extender and the +pre-Symantec debugger. + +One caveat - if you got the 6.0 release, be sure to get the free 6.1 update! + + +WATCOM C/C++ (WC++) +------------------- + +Watcom is the technological industry leader, performing feats of optimization +and floating point speed other vendors only dream of. The cost is compile +speed, which has been described (somewhat unfairly) as glacial. For all its +technical excellence, WC++ is still a niche market compiler like SC++. As +such, it's 3rd party support is poor, but many have found that Microsoft C +libraries will work just fine with WC++. Like SC++, and unlike BC++ and VC++, +WC++ provides documented support for embedded systems work, although not to +nearly the same degree as Metaware (see below). + +Also, like SC++, WC++ supports 32-bit code generation. WC++ is the compiler +of choice for many OEMs, such as Novell, who want only the best supporting +code for their products. MSC/VC++ compatibility is excellent, but watch out +for Watcom's sensitivity to proper _cdecl declarations, implemented in Watcom +via a pragma rather than as a built-in language feature. Watcom sells both +16- and 32-bit versions of its C/C++ compiler. The best deal is to buy the +32-bit compiler and then purchase the 16-bit upgrade pack. + +Where Watcom really shines is its support for a multitude of environments +with the same compiler(s). Supported are DOS, Win3.1, Win32s, NT, OS/2 (1.x & +2.x), Netware 386, AutoCAD ADS, QNX, Phar Lap and Rational DOS extenders. +With such a bewildering array of targets, compilation is relatively +straightforward but the linker has a steep learning curve. + +Watcom remains the only one of the "big name" compilers to not ofer an IDE, +if that's important to you or you don't own a "real" programmer's editor. + + +METAWARE HIGH-C/C++ (HC++) +-------------------------- + +HC++ is the darling of some segments of the embedded systems market. As such, +it's a lot like WC++, only not quite as good and a lot weirder since it +offers detailed control over every aspect of the executable. Most WC++ +comments apply, except for the ones relating to quality of generated code. +HC++'s code is quite good, but seems to be showing its niche market +orientation (any one remember Manx Aztec C?) + + +TOPSPEED C/C++ (TSC++) +---------------------- + +TSC++ has had a rocky life, getting off to a late start in the market and +never having really quite caught on. Originally, TSC++ was a Turbo C clone +which shared tools and environments with its sister Modula-2 compiler. More +recent versions have extended this by using a modular approach with an +environment supporting "plug-in" compilers for various languages which can +all be used together. The company was recently acquired by Clarion. + +TSC++'s undisputed biggest strength is its smart linker and various features +added to facilitate mixed-language programming (Modula-2, for example, +supports multi-threaded code). Using this technology, you can count on TSC++ +to almost always produce the smallest executables for a given piece of source +code. The library, written almost exclusively in assembly, is also excellent +and contributes to the frugal use of run-time memory. Unfortunately, +compiler-generated code is typically not of the same quality. + +Drawbacks include almost non-existant 3rd party support and the pervasive IDE +which feels more at home to Modula-2 programmers than C programmers. + + +GNU C/C++ (GCC, G++) +-------------------- + +Available from the Free Software Foundation, GCC and G++ are the only +compilers listed here available for free without a guilty conscience. +Originally written for Unix systems, there are several DOS ports available, +all of which require some sort of DOS extender technology built-in in order +to work in DOS's limited memory. OS/2 ports obviously don't share this +limitation. Along with SC++, WC++, and HC++, the gnu compilers round out the +list of full ISO/ANSI/ARM compilers with explicit support for embedded +systems. + +Performance is decent, but not earth-shattering, and executable tends to +exhibit lots of bloat. If you plan to use one of these to write commercial +code, be sure and read the license agreement *very* closely. + + +DUNFIELD MICRO-C +---------------- + +There have been many "small" or "tiny" C's over the years, some useful for +teaching the rudiments of compiler construction, others not much use for +anything. Small C's typically lack structs, unions, bit fields, and even long +integers. + +Why bother listing this one then? + +First of all, Micro-C is an evolving product which, as of version 3, now +includes many features such as structs and unions not normally associated +with small C's. + +Also, the source code (available when you register the shareware version) is +quite decent and really can teach you something about compiler internals. But +Micro-C is genuinely useful for a lot more reasons. + +The author also produces cross-assemblers for a variety of microprocessors +and provides plug-in code generators for his C compiler to use with those +chips as well. The 80x86 version comes ready to compile either PC or embedded +code. Included in the PC library are support for writing TSR's, interrupt- +driven serial I/O, and screen windowing. Amazingly, it also sports an +optimizer, but requires MASM or equivalent for compiling PC applications. + +Supporting small and tiny model only, Micro-C executables are phenomenally +small. "Hello world" programs that run 5-6K on other compilers run under 600 +bytes when compiled with Micro-C. + +One other point needs to be mentioned with respect to Micro-C... Although it +is *a* small C, it has no code commonality with *the* Small C from the book +of the same name. This is important since there are a number of variants of +Small C available, all not much better than the original. Micro-C, OTOH, was +written by Dave Dunfield completely from scratch and is a *much* better +designed piece of code and certainly much more instructive to fledgling +compiler writers. His better design is evinced in code quality and execution +speed. + + +PCC +--- + +The Personal C Compiler is available as shareware. It used to be marketed as +the deSmet C compiler and had a generally good reputation for quick compile +times and tight code. Unfortunately, the product hasn't been seriously +upgraded in quite a while and can't stand too much comparison. It's horribly +non-ANSI compliant, has a weaker set of library functions than Micro-C, +features non-standard file formats, and is generally incompatible with most +published C code + +If price is your concern, Mix Power C costs less to buy than PCC and offers +better performance along with the ANSI compliance that PCC lacks. If you plan +on using an unregistered copy, Gnu C/C++ are vastly superior and are legally +free. If you're attracted to its tight, fast code and can live with quirks +and without ANSI compliance, go with Dunfield Micro-C. diff --git a/reference/C/CONTRIB/SNIP/whicharc.c b/reference/C/CONTRIB/SNIP/whicharc.c new file mode 100755 index 0000000..8ca8ce8 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/whicharc.c @@ -0,0 +1,251 @@ +#include <stdio.h> +#include <string.h> + +/* -------------------------------------------------------------------- + Module: WHICHARC.C + Subject: tries to determine the archiver used to compress files + Author: Heinz Ozwirk & David Gersic + modified for SNIPPETS by Bob Stout + Status: public domain + Started: 28.09.1991 13:35:57 + Modified: 13.10.1991 14:15:57 + Modified: 5 January, 1992 11:50am by David Gersic + Added return codes for self extracting archive files. + Modified: 16 January, 1992, 4:15pm by David Gersic + Added Pak and ARC ver. 6 with information from Richard + Vanhouten @1:272/38. I'm not sure that this code works + perfectly for those formats, as his message seems to + indicate that the entire archive has to be scanned for + headers to check before the type can be perfectly + determined. It seems to work for test archives produced + here, but may not work for all archives. + -------------------------------------------------------------------- + Prototype: int WhichArc(char *pName) + pName address of full path name of file to examine + Result -1: file not found + UNKNOWN: unknown packer + ARC: ARC or PKARC + ARJ: ARJ + LHA: LHARC or LHA + ZIP: PKZIP + ZOO: Zoo + PAK: Pak + ARC7: ARC later than ver. 6.02 + SFXARC: Self Extracting PKARC + SFXARJ: Self Extracting ARJ + SFXLHARC:Self Extracting LHARC + SFXLHA: Self Extracting LHA + SFXZIP: Self Extracting ZIP + SFXPAK: Self Extracting Pak + SFXARC6: Self Extracting ARC later than ver. 6.02 + EXE: MS DOS executable of unknown type + + LHARC/LHA + No archive header. WhichArc examines the checksum of the first + file header. If the checksum is valid and if the string -lh?- + is found, LHA or LHARC is assumed. + + ARJ + If a file starts with 0x60, 0xEA, ARJ is assumed. + + ZIP + If the file begins with "PK", PKZIP is assumed. + + ZOO + Zoo'ed archives always start with "ZOO x.xx Archive". WhichArc + only looks for "ZOO". + + ARC + No header. Files starting with 0x1A are assumed to be ARCed. + + PAK + Similar to ARC files, but if the second byte of the header is 0x0a or + 0x0b, it was created by Pak. + + ARC7 + Similar to ARC, but if the second byte of the header is 0x14 or + higher, it was created by an Arc version later than 6.02. + + SFX* + All of the SFX files start with a small decompressor. Seek past + the decompressor and repeat the above checks. + -------------------------------------------------------------------- */ + + +typedef unsigned char BYTE; + +enum ArcType { ArcERR=-1, UNKNOWN, ARC, ZOO, ARJ, LHARC, LHA, ZIP, PAK, ARC7, + SFXARC, SFXARJ, SFXLHARC, SFXLHA, SFXZIP, SFXARC7, SFXPAK, EXE + }; + +enum ArcType WhichArc(char *pName) +{ + FILE *fp; + BYTE header[128]; + int c, i, n; + enum ArcType retval = ArcERR; + + memset(header, 0, sizeof(header)); + fp = fopen(pName, "rb"); + if (fp == NULL) + goto EXIT; /* error opening file */ + n = fread(header, sizeof(BYTE), sizeof(header) - sizeof(BYTE), fp); + + if (n <= 0) /* error reading from file */ + goto EXIT; + + if (n >= 7 && n >= header[0] + 2) + { + for (c = 0, i = header[0]; i--; c += (header+2)[i]) + ; + if (((BYTE)(c & 0x00FF)) == header[1] + && header[2] == '-' + && header[3] == 'l' + && header[4] == 'h' + && header[6] == '-') + { + retval = (header[5] > '1') ? LHA : LHARC; + goto EXIT; + } + } + + if (n >= 2) + { + if (header[0] == 0x60 && header[1] == 0xEA) + { + retval = ARJ; + goto EXIT; + } + if (header[0] == 'P' && header[1] == 'K') + { + retval = ZIP; + goto EXIT; + } + } + + if (n >= 3 && header[0] == 'Z' && header[1] == 'O' && header[2] == 'O') + { + retval = ZOO; + goto EXIT; + } + + if (n >= 25 && header[0] == 0x1A) + { + if (header[1]>0x14) + retval = ARC7; + else if (header[1]==0x0a || header[1]==0x0b) + retval = PAK; + else retval = ARC; + goto EXIT; + } + + if (0 == strncmp(header, "MZ", 2)) /* some sort of .EXE file */ + { + /* test for SFX ARJ file */ + + memset(header, 0, sizeof(header)); + fseek(fp, 0x39ba, SEEK_SET); + n = fread(header, sizeof(BYTE), + sizeof(header) - sizeof(BYTE), fp); + if (n > 1 && header[0] == 0x60 && header[1] == 0xea) + { + retval = SFXARJ; + goto EXIT; + } + + /* test for SFX LHARC file */ + + memset(header, 0, sizeof(header)); + fseek(fp, 0x653, SEEK_SET); + n = fread(header, sizeof(BYTE), + sizeof(header) - sizeof(BYTE), fp); + for (c = 0, i = header[0]; i--; c += (header+2)[i]) + ; + if (n >= 7 && n >= header[0] + 2) + { + if (((BYTE)(c & 0x00FF)) == header[1] + && header[2] == '-' + && header[3] == 'l' + && header[4] == 'h' + && header[6] == '-') + { + retval = SFXLHARC; + goto EXIT; + } + } + + /* test for SFX LHA file */ + + memset(header, 0, sizeof(header)); + fseek(fp, 0x799, SEEK_SET); + n = fread(header, sizeof(BYTE), + sizeof(header) - sizeof(BYTE), fp); + for (c = 0, i = header[0]; i--; c += (header+2)[i]) + ; + if (n >= 7 && n >= header[0] + 2) + { + if (((BYTE)(c & 0x00FF)) == header[1] + && header[2] == '-' + && header[3] == 'l' + && header[4] == 'h' + && header[6] == '-') + { + retval = SFXLHA; + goto EXIT; + } + } + + /* test for SFX ZIP file */ + + memset(header, 0, sizeof(header)); + fseek(fp, 0x31f0, SEEK_SET); + n = fread(header, sizeof(BYTE), + sizeof(header) - sizeof(BYTE), fp); + if (n > 1 && header[0] == 'P' && header[1] == 'K') + { + retval = SFXZIP; + goto EXIT; + } + + /* test for SFX PKARC file */ + + memset(header, 0, sizeof(header)); + fseek(fp,0x261e,SEEK_SET); + n = fread(header, sizeof(BYTE), + sizeof(header) - sizeof(BYTE), fp); + if (n > 1 && header[0] == 0x1a) + { + if (header[1]>0x14) + retval = SFXARC7; + else if (header[1]==0x0a || header[1]==0x0b) + retval = SFXPAK; + else retval = SFXARC; + } + else retval = EXE; + } + retval = UNKNOWN; +EXIT: fclose(fp); + return retval; +} + +#ifdef TEST + +int main(int argc,char *argv[]) +{ + char *arc_types[]={"UNKNOWN", "ARC", "ZOO", "ARJ", "LHARC", "LHA", + "ZIP", "PAK", "PAK", "ARC7", "SFXARC", "SFXARJ", + "SFXLHARC", "SFXLHA", "SFXZIP", "SFXARC7", "SFXPAK", + "EXE"}; + + while (--argc) + { + enum ArcType which; + + if (ArcERR == (which = WhichArc(*++argv))) + printf("File error accessing %s\n", *argv); + else printf("%s archive type is %s\n", *argv, arc_types[which]); + } + return(0); +} + +#endif diff --git a/reference/C/CONTRIB/SNIP/windchil.c b/reference/C/CONTRIB/SNIP/windchil.c new file mode 100755 index 0000000..c868773 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/windchil.c @@ -0,0 +1,19 @@ +/* +** Wind Chill for exposed human skin, expressed as a function of wind +** speed in Miles per Hour and temperature in degrees Fahrenheit. +** +** Public domain from numerous published references. +*/ + +#include <math.h> + +double wind_chill(int wind_speed, int temp) +{ + if (4 > wind_speed) + return (double)temp; + else + { + return (((10.45 + (6.686112 * sqrt((double) wind_speed)) + - (.447041 * wind_speed)) / 22.034 * (temp - 91.4)) + 91.4); + } +} diff --git a/reference/C/CONTRIB/SNIP/wordwrap.c b/reference/C/CONTRIB/SNIP/wordwrap.c new file mode 100755 index 0000000..a4da431 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/wordwrap.c @@ -0,0 +1,92 @@ +/* +** WORDWRAP.C - Simple CRT word wrap demonstration routine +** +** public domain by Robert Morgan +*/ + +#include <stdio.h> +#include <conio.h> +#include <string.h> + +int get_ln(int rmargin); +void clr_eol(const int curpos, const int pos); + +void main() +{ + printf("Enter text. Press CTRL-A to quit.\n"); + while((get_ln(75)) != 0) /* Change 75 to whatever number you */ + ; /* wish to be the right margin */ +} + +void clr_eol(const int curpos, const int pos) +{ + int distance; + int count; + + distance = curpos - pos; + + for (count = 1; count <= distance; count++) + putch('\b'); + for (count = 1; count <= distance; count++) + putch(' '); +} + +int get_ln(int rmargin) +{ + char word[80]; + static int wordpos = 0; + static int curpos = 1; + static int ch = 0; + static int pos = 0; + + word[wordpos] = '\0'; + + while (ch != 1) + { + ch = getch(); + + switch(ch) + { + case 1: + return(0); + case ' ': + pos = curpos; + putch(' '); + curpos++; + wordpos = 0; + word[0] = '\0'; + break; + case '\b': + putch('\b'); + curpos--; + if (wordpos > 0) + wordpos--; + break; + case '\r': + puts("\r"); + wordpos = 0; + word[wordpos] = '\0'; + curpos = 1; + pos = 0; + break; + default: + putch(ch); + word[wordpos] = (char)ch; + curpos++; + wordpos++; + break; + } + + if(curpos == rmargin) + { + word[wordpos] = '\0'; + clr_eol(curpos,pos); + wordpos = 0; + curpos = strlen(word); + pos = 0; + puts("\r"); + printf("%s",word); + } + } + return -1; +} diff --git a/reference/C/CONTRIB/SNIP/x00api.c b/reference/C/CONTRIB/SNIP/x00api.c new file mode 100755 index 0000000..927ed04 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/x00api.c @@ -0,0 +1,411 @@ +/* + * X00API.C: X00 FOSSIL driver + * + * Created by R.F. Pels. + * modified by Bob Stout + * Placed in the public domain by R.F. Pels. + */ + +#include "x00api.h" +#include <dos.h> + +static union REGS x00regs; +static struct SREGS x00sregs; +int x00error = 0; + +#if __cplusplus + extern "C" { +#endif + +#ifdef __TURBOC__ + #define PEEK(s,o) peek(s,o) +#else /* MSC or ZTC */ + #define PEEK(s,o) *((unsigned _far *)(MK_FP((s),(o)))) +#endif + +#ifndef MK_FP + #define MK_FP(seg,offset) \ + ((void _far *)(((unsigned long)(seg)<<16) | (unsigned)(offset))) +#endif + +unsigned int x00_detect(void) +{ + unsigned int segofx00; + unsigned int ofsofx00; + + /* Peek in interrupt vector table for start of FOSSIL */ + + ofsofx00 = PEEK(0, X00_VECTOR * 4); + segofx00 = PEEK(0, (X00_VECTOR * 4) + 2); + + /* Peek in start of FOSSIL + X00_IDOFFSET */ + + return (PEEK(segofx00, ofsofx00 + X00_IDOFFSET)); +} + +FOSSILSTATUS x00_set(unsigned char set, PORT port) +{ + FOSSILSTATUS retval; + + x00regs.x.ax = SET_BAUDRATE | set; + x00regs.x.dx = port; + int86(X00_VECTOR, &x00regs, &x00regs); + retval.statusword = x00regs.x.ax; + return retval; +} + +FOSSILSTATUS x00_tx_char(unsigned char c, PORT port) +{ + FOSSILSTATUS retval; + + x00regs.x.ax = TX_CHAR | c; + x00regs.x.dx = port; + int86(X00_VECTOR, &x00regs, &x00regs); + retval.statusword = x00regs.x.ax; + return retval; +} + +unsigned char x00_rx_char(PORT port) +{ + x00regs.x.ax = RX_CHAR; + x00regs.x.dx = port; + int86(X00_VECTOR, &x00regs, &x00regs); + return (unsigned char)(x00regs.x.ax & 0xff); +} + +FOSSILSTATUS x00_status(PORT port) +{ + FOSSILSTATUS retval; + + x00regs.x.ax = STATUS; + x00regs.x.dx = port; + int86(X00_VECTOR, &x00regs, &x00regs); + retval.statusword = x00regs.x.ax; + return retval; +} + +FOSSILINIT x00_init(PORT port, unsigned char far *ctlc_flagbyte) +{ + FOSSILINIT retval; + + x00regs.x.ax = INITIALIZE; + if (ctlc_flagbyte != (unsigned char far *)0) + { + x00regs.x.dx = 0x00ff; + x00regs.x.bx = 0x4F50; + segread(&x00sregs); + x00sregs.es = FP_SEG(ctlc_flagbyte); + x00regs.x.cx = FP_OFF(ctlc_flagbyte); + } + else + { + x00regs.x.bx = 0x0000; /* in any case _NOT_ 0x4f50 */ + x00regs.x.dx = port; + } + int86x(X00_VECTOR, &x00regs, &x00regs, &x00sregs); + retval.result = x00regs.x.ax; + retval.max_function = (unsigned char)(x00regs.x.bx & 0xff); + retval.revision = (unsigned char)(x00regs.x.bx >> 8); + return retval; +} + +void x00_deinit(PORT port) +{ + x00regs.x.ax = DEINITIALIZE; + x00regs.x.dx = port; + int86(X00_VECTOR, &x00regs, &x00regs); +} + +unsigned int x00_raise_dtr(PORT port) +{ + unsigned int retval; + + x00regs.x.ax = RAISE_DTR; + x00regs.x.dx = port; + int86(X00_VECTOR, &x00regs, &x00regs); + if ((x00regs.x.ax & 0x0001) == 1) + { + retval = X00_DTR_HIGH; + } + else retval = X00_DTR_LOW; + return retval; +} + +unsigned int x00_lower_dtr(PORT port) +{ + unsigned int retval; + + x00regs.x.ax = LOWER_DTR; + x00regs.x.dx = port; + int86(X00_VECTOR, &x00regs, &x00regs); + if ((x00regs.x.ax & 0x0001) == 1) + { + retval = X00_DTR_HIGH; + } + else retval = X00_DTR_LOW; + return retval; +} + +FOSSILSYSINFO x00_sysinfo(void) +{ + FOSSILSYSINFO retval; + + x00regs.x.ax = GET_SYS_INFO; + int86(X00_VECTOR, &x00regs, &x00regs); + retval.tick_number = (unsigned char)(x00regs.x.ax & 0xff); + retval.ticks_per_second = (unsigned char)(x00regs.x.ax >> 8); + retval.approx_ms_per_tick = x00regs.x.dx; + return retval; +} + +void x00_flush_output(PORT port) +{ + x00regs.x.ax = FLUSH_OUTPUT; + x00regs.x.dx = port; + int86(X00_VECTOR, &x00regs, &x00regs); +} + +void x00_purge_output(PORT port) +{ + x00regs.x.ax = PURGE_OUTPUT; + x00regs.x.dx = port; + int86(X00_VECTOR, &x00regs, &x00regs); +} + +void x00_purge_input(PORT port) +{ + x00regs.x.ax = PURGE_INPUT; + x00regs.x.dx = port; + int86(X00_VECTOR, &x00regs, &x00regs); +} + +unsigned int x00_tx_char_nowait(unsigned char c, PORT port) +{ + unsigned int retval; + + x00regs.x.ax = TX_CHAR_NOWAIT | c; + x00regs.x.dx = port; + int86(X00_VECTOR, &x00regs, &x00regs); + if ((x00regs.x.ax & 0x0001) == 1) + { + retval = X00_OK; + } + else retval = X00_CHAR_NOT_SENT; + return retval; +} + +unsigned int x00_peek_ahead_input(PORT port) +{ + x00regs.x.ax = PEEK_AHEAD_INPUT; + x00regs.x.dx = port; + int86(X00_VECTOR, &x00regs, &x00regs); + return x00regs.x.ax; +} + +unsigned int x00_peek_ahead_kbd(void) +{ + x00regs.x.ax = PEEK_AHEAD_KBD; + int86(X00_VECTOR, &x00regs, &x00regs); + return x00regs.x.ax; +} + +unsigned int x00_read_kbd(void) +{ + x00regs.x.ax = READ_KBD; + int86(X00_VECTOR, &x00regs, &x00regs); + return x00regs.x.ax; +} + +void x00_flow_control(FOSSILFLOWCTRL f, PORT port) +{ + x00regs.x.ax = FLOW_CONTROL | 0xf0 | f.flowword; + x00regs.x.dx = port; + int86(X00_VECTOR, &x00regs, &x00regs); +} + +unsigned int x00_ctlc_ctlk_check(FOSSILCTLCCTLK c, PORT port) +{ + x00regs.x.ax = CTLC_CTLK_CHECK | c.checkword; + x00regs.x.dx = port; + int86(X00_VECTOR, &x00regs, &x00regs); + return x00regs.x.ax; +} + +void x00_set_cup(unsigned char row, unsigned char col) +{ + x00regs.x.ax = SET_CUP; + x00regs.x.dx = (row << 8) | col; + int86(X00_VECTOR, &x00regs, &x00regs); +} + +void x00_get_cup(unsigned char *row, unsigned char *col) +{ + x00regs.x.ax = GET_CUP; + int86(X00_VECTOR, &x00regs, &x00regs); + *col = (unsigned char)(x00regs.x.dx & 0xff); + *row = (unsigned char)(x00regs.x.dx >> 8); +} + +void x00_write_ANSI_char(unsigned char c) +{ + x00regs.x.ax = WRITE_ANSI_CHAR | c; + int86(X00_VECTOR, &x00regs, &x00regs); +} + +void x00_enable_watchdog(PORT port) +{ + x00regs.x.ax = ENABLE_WATCHDOG; + x00regs.x.dx = port; + int86(X00_VECTOR, &x00regs, &x00regs); +} + +void x00_disable_watchdog(PORT port) +{ + x00regs.x.ax = DISABLE_WATCHDOG; + x00regs.x.dx = port; + int86(X00_VECTOR, &x00regs, &x00regs); +} + +void x00_write_BIOS_char(unsigned char c) +{ + x00regs.x.ax = WRITE_BIOS_CHAR | c; + int86(X00_VECTOR, &x00regs, &x00regs); +} + +unsigned int x00_insert_tick_func(void (far *tickfunc)()) +{ + unsigned int retval; + + x00regs.x.ax = INSERT_TICK_FUNC; + x00regs.x.dx = FP_OFF(tickfunc); + segread(&x00sregs); + x00sregs.es = FP_SEG(tickfunc); + int86x(X00_VECTOR, &x00regs, &x00regs, &x00sregs); + if (x00regs.x.ax == 0x0000) + { + retval = X00_OK; + } + else retval = X00_INS_TICK; + return retval; +} + +unsigned int x00_delete_tick_func(void (far *tickfunc)()) +{ + unsigned int retval; + + x00regs.x.ax = DELETE_TICK_FUNC; + x00regs.x.dx = FP_OFF(tickfunc); + segread(&x00sregs); + x00sregs.es = FP_SEG(tickfunc); + int86x(X00_VECTOR, &x00regs, &x00regs, &x00sregs); + if (x00regs.x.ax == 0x0000) + { + retval = X00_OK; + } + else retval = X00_DEL_TICK; + return retval; +} + +void x00_boot_machine(unsigned int boottype) +{ + x00regs.x.ax = BOOT_MACHINE | (boottype & 0x0001); + int86(X00_VECTOR, &x00regs, &x00regs); +} + +unsigned int x00_read_block(unsigned int count, void far *buf, PORT port) +{ + x00regs.x.ax = READ_BLOCK; + x00regs.x.cx = count; + x00regs.x.dx = port; + segread(&x00sregs); + x00sregs.es = FP_SEG(buf); + x00regs.x.di = FP_OFF(buf); + int86x(X00_VECTOR, &x00regs, &x00regs, &x00sregs); + return x00regs.x.ax; +} + +unsigned int x00_write_block(unsigned int count, void far *buf, PORT port) +{ + x00regs.x.ax = WRITE_BLOCK; + x00regs.x.cx = count; + x00regs.x.dx = port; + segread(&x00sregs); + x00sregs.es = FP_SEG(buf); + x00regs.x.di = FP_OFF(buf); + int86x(X00_VECTOR, &x00regs, &x00regs, &x00sregs); + return x00regs.x.ax; +} + +void x00_start_break_signal(PORT port) +{ + x00regs.x.ax = START_BREAK_SIGNAL; + x00regs.x.dx = port; + int86(X00_VECTOR, &x00regs, &x00regs); +} + +void x00_stop_break_signal(PORT port) +{ + x00regs.x.ax = STOP_BREAK_SIGNAL; + x00regs.x.dx = port; + int86(X00_VECTOR, &x00regs, &x00regs); +} + +unsigned int x00_get_driverinfo(void far *buf, PORT port) +{ + x00regs.x.ax = GET_DRIVER_INFO; + x00regs.x.cx = sizeof(FOSSILINFO); + segread(&x00sregs); + x00sregs.es = FP_SEG(buf); + x00regs.x.di = FP_OFF(buf); + x00regs.x.dx = port; + int86x(X00_VECTOR, &x00regs, &x00regs, &x00sregs); + return x00regs.x.ax; +} + +unsigned int x00_install_appendage(unsigned char appcode, + void (far *appfunc)()) +{ + unsigned int retval; + + x00regs.x.ax = INSTALL_APPENDAGE | appcode; + segread(&x00sregs); + x00sregs.es = FP_SEG(appfunc); + x00regs.x.dx = FP_OFF(appfunc); + int86x(X00_VECTOR, &x00regs, &x00regs, &x00sregs); + if (x00regs.x.ax == X00_PRESENT) + { + if ((x00regs.x.bx & 0xff00) == 1) + { + retval = X00_OK; + } + else retval = X00_INS_APP; + } + else retval = X00_NOT_HERE; + return retval; +} + +unsigned int x00_remove_appendage(unsigned char appcode, + void (far *appfunc)()) +{ + unsigned int retval; + + x00regs.x.ax = REMOVE_APPENDAGE | appcode; + segread(&x00sregs); + x00sregs.es = FP_SEG(appfunc); + x00regs.x.dx = FP_OFF(appfunc); + int86x(X00_VECTOR, &x00regs, &x00regs, &x00sregs); + if (x00regs.x.ax == X00_PRESENT) + { + if ((x00regs.x.bx & 0xff00) == 1) + { + retval = X00_OK; + } + else retval = X00_REM_APP; + } + else retval = X00_NOT_HERE; + return retval; +} + +#if __cplusplus + } +#endif diff --git a/reference/C/CONTRIB/SNIP/x00api.h b/reference/C/CONTRIB/SNIP/x00api.h new file mode 100755 index 0000000..7d4e43a --- /dev/null +++ b/reference/C/CONTRIB/SNIP/x00api.h @@ -0,0 +1,236 @@ +/* + * X00API.H - X00 FOSSIL driver HLLAPI + * + * Created by R.F. Pels. + * modified by Bob Stout + * Placed in the public domain by R.F. Pels. + */ + +#ifndef __X00API_H /* Prevent double inclusion */ +#define __X00API_H + +/* FOSSIL specifics */ + +#define X00_VECTOR 0x14 +#define X00_IDOFFSET 6 + +/* FOSSIL function request codes */ + +#define SET_BAUDRATE 0x0000 +#define TX_CHAR 0x0100 +#define RX_CHAR 0x0200 +#define STATUS 0x0300 +#define INITIALIZE 0x0400 +#define DEINITIALIZE 0x0500 +#define RAISE_DTR 0x0601 +#define LOWER_DTR 0x0600 +#define GET_SYS_INFO 0x0700 +#define FLUSH_OUTPUT 0x0800 +#define PURGE_OUTPUT 0x0900 +#define PURGE_INPUT 0x0A00 +#define TX_CHAR_NOWAIT 0x0B00 +#define PEEK_AHEAD_INPUT 0x0C00 +#define PEEK_AHEAD_KBD 0x0D00 +#define READ_KBD 0x0E00 +#define FLOW_CONTROL 0x0F00 +#define CTLC_CTLK_CHECK 0x1000 +#define SET_CUP 0x1100 +#define GET_CUP 0x1200 +#define WRITE_ANSI_CHAR 0x1300 +#define ENABLE_WATCHDOG 0x1401 +#define DISABLE_WATCHDOG 0x1400 +#define WRITE_BIOS_CHAR 0x1500 +#define INSERT_TICK_FUNC 0x1601 +#define DELETE_TICK_FUNC 0x1600 +#define BOOT_MACHINE 0x1700 +#define READ_BLOCK 0x1800 +#define WRITE_BLOCK 0x1900 +#define START_BREAK_SIGNAL 0x1A01 +#define STOP_BREAK_SIGNAL 0x1A00 +#define GET_DRIVER_INFO 0x1B00 +#define INSTALL_APPENDAGE 0x7e00 +#define REMOVE_APPENDAGE 0x7f00 + +/* port numbers and variable type of portnumber in calls */ + +#define PORTCOM1 0 +#define PORTCOM2 1 +#define PORTCOM3 2 +#define PORTCOM4 3 +#define PORTCOM5 4 +#define PORTCOM6 5 +#define PORTCOM7 6 +#define PORTCOM8 7 +#define PORTSPECIAL 0x00ff + +typedef unsigned int PORT; + +/* defines components of baud settings call */ + +#define BAUD300 0x40 +#define BAUD600 0x60 +#define BAUD1200 0x80 +#define BAUD2400 0xa0 +#define BAUD4800 0xc0 +#define BAUD9600 0xe0 +#define BAUD19200 0x00 +#define BAUD38400 0x20 +#define PARITYNONE 0x00 +#define PARITYODD 0x08 +#define PARITYNONEALT 0x10 +#define PARITYEVEN 0x18 +#define STOP1BIT 0x00 +#define STOP2BIT 0x04 +#define WORD5BIT 0x00 +#define WORD6BIT 0x01 +#define WORD7BIT 0x02 +#define WORD8BIT 0x03 +#define FIDOSETTING PARITYNONE | STOP1BIT | WORD8BIT +#define OPUSSETTING PARITYNONE | STOP1BIT | WORD8BIT +#define SEADOGSETTING PARITYNONE | STOP1BIT | WORD8BIT + +/* Error numbers */ + +#define X00_OK 0 +#define X00_NOT_HERE 100 +#define X00_CHAR_NOT_SENT 101 +#define X00_NO_INPUT 0xffff +#define X00_NO_KEY 0xffff +#define X00_INS_TICK 104 +#define X00_DEL_TICK 105 +#define X00_INS_APP 106 +#define X00_REM_APP 107 +#define X00_DTR_HIGH 108 +#define X00_DTR_LOW 109 + + +/* FOSSIL initcall result type */ + +#define X00_PRESENT 0x1954 + +typedef struct { + unsigned int result; + unsigned char max_function; + unsigned char revision; + } FOSSILINIT; + +/* FOSSIL status return type: all fields are 1 if condition exists */ + +typedef union { + struct STATUSBITS { + unsigned int : 3; + unsigned int alwayshigh : 1; + unsigned int : 3; + unsigned int carrier_detect : 1; + unsigned int chars_in_input : 1; + unsigned int input_overrun : 1; + unsigned int : 3; + unsigned int output_not_full : 1; + unsigned int output_empty : 1; + unsigned int : 1; + } statusbits; + unsigned int statusword; + } FOSSILSTATUS; + +/* FOSSIL info type */ + +typedef struct { + unsigned int size; + unsigned char version; + unsigned char revision; + unsigned int ofs_fossil_id; + unsigned int seg_fossil_id; + unsigned int input_size; + unsigned int input_avail; + unsigned int output_size; + unsigned int output_avail; + unsigned char screen_width; + unsigned char screen_height; + unsigned char baud_rate_mask; + } FOSSILINFO; + +/* FOSSIL system info type */ + +typedef struct { + unsigned char tick_number; + unsigned char ticks_per_second; + unsigned int approx_ms_per_tick; + } FOSSILSYSINFO; + +/* FOSSIL flow control type */ + +typedef union { + struct FLOWBITS { + unsigned char xonxoff : 1; + unsigned char ctsrts : 1; + unsigned char remote_xonxoff : 1; + unsigned char : 5; + } flowbits; + unsigned char flowword; + } FOSSILFLOWCTRL; + +/* FOSSIL checks control type */ + +#define X00_CTLCK 0x0001 +#define X00_NO_CTLCK 0x0000 + +typedef union { + struct CHECKBITS { + unsigned char ctlc_ctlk : 1; + unsigned char stop_transmitter : 1; + unsigned char : 6; + } checkbits; + unsigned char checkword; + } FOSSILCTLCCTLK; + +#define COLDBOOT 0 +#define WARMBOOT 1 + +#if __cplusplus + extern "C" { +#endif + +unsigned int x00_detect(void); +FOSSILSTATUS x00_set(unsigned char set, PORT port); +FOSSILSTATUS x00_tx_char(unsigned char c, PORT port); +unsigned char x00_rx_char(PORT port); +FOSSILSTATUS x00_status(PORT port); +FOSSILINIT x00_init(PORT port, unsigned char far *ctlc_flagbyte); +void x00_deinit(PORT port); +unsigned int x00_raise_dtr(PORT port); +unsigned int x00_lower_dtr(PORT port); +FOSSILSYSINFO x00_sysinfo(void); +void x00_flush_output(PORT port); +void x00_purge_output(PORT port); +void x00_purge_input(PORT port); +unsigned int x00_tx_char_nowait(unsigned char c, PORT port); +unsigned int x00_peek_ahead_input(PORT port); +unsigned int x00_peek_ahead_kbd(void); +unsigned int x00_read_kbd(void); +void x00_flow_control(FOSSILFLOWCTRL f, PORT port); +unsigned int x00_ctlc_ctlk_check(FOSSILCTLCCTLK c, PORT port); +void x00_set_cup(unsigned char row, unsigned char col); +void x00_get_cup(unsigned char *row, unsigned char *col); +void x00_write_ANSI_char(unsigned char c); +void x00_enable_watchdog(PORT port); +void x00_disable_watchdog(PORT port); +void x00_write_BIOS_char(unsigned char c); +unsigned int x00_insert_tick_func(void (_far *tickfunc)()); +unsigned int x00_delete_tick_func(void (_far *tickfunc)()); +void x00_boot_machine(unsigned int boottype); +unsigned int x00_read_block(unsigned int count, void far *buf, PORT port); +unsigned int x00_write_block(unsigned int count, void far *buf, +PORT port); +void x00_start_break_signal(PORT port); +void x00_stop_break_signal(PORT port); +unsigned int x00_get_driverinfo(void far *buf, PORT port); +unsigned int x00_install_appendage(unsigned char appcode, + void (_far *appfunc)()); +unsigned int x00_remove_appendage(unsigned char appcode, + void (_far *appfunc)()); + +#if __cplusplus + } +#endif + +#endif /* __X00API_H */ diff --git a/reference/C/CONTRIB/SNIP/xfile.c b/reference/C/CONTRIB/SNIP/xfile.c new file mode 100755 index 0000000..7be9d51 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/xfile.c @@ -0,0 +1,200 @@ +/* xfile.c -- implementation for fast line buffered files +** +** Currently (Sat 06-15-1991) XFILEs are for reading CR-LF terminated lines +** from MS-DOS text files. Period. It's not that the method can't be used +** as well for output buffering, or (in some form) for binary files, it's +** that such are handled fast enough to suit me already, whereas text mode +** input performance leaves me wishing for more speed. This attempts to +** solve that problem. +** +** Sun 06-16-1991 -- CR-LF accepted, but so is bare LF now; the extracted +** line does NOT have a NEWLINE at the end anymore (which will likely be +** a mixed blessing...) +** +** The code should be fairly portable: if/when I get around to polishing it +** (and that won't be until I've used it some and am sure it's stable) I'll +** be aiming for near-ANSI portability; for now I'm not pushing so very hard +** for that. +** +** The semantics are a bit odd: the lines are returned in a buffer that the +** XFILE owns, and may be altered by a call to xgetline or xclose. For +** applications that resent this, XFILEs probably aren't a big win anyway, +** but there might be some cases where using XFILE and copying (some) lines +** is still a good idea. The performance with long lines is good: it can +** handle lines the size of the buffer, though it may truncate up to one +** QUANTUM less one bytes "early": this depends on the location of the start +** of the line in the buffer when we begin scanning. In practice, XBUFSIZE +** is probably larger than you'd set for a line buffer size anyway... +** +** INTERNALS: +** +** Reading the first buffer's worth at open time makes the EOF case easier to +** detect. +** +** TO DO: +** +** clean up xgetline! +*/ + +#include <stdlib.h> +#include <string.h> +#include "xfile.h" + +#if !defined(__ZTC__) && !defined(__TURBOC__) + static int DOS_OPEN(const char *name, int mode, ...) + { + int hdl; + + if (0 == _dos_open(name, mode, &hdl)) + return hdl; + else return -1; + } + + static int READ(int fd, void *buf, size_t len) + { + unsigned count; + + if (0 == _dos_read(fd, buf, len, &count)) + return count; + else return -1; + } +#endif + +#ifndef XBUFN /* set default # of quanta in buffer, allow -D */ + #define XBUFN 8 +#endif + +#define QUANTUM 512 +#define XBUFSIZE (XBUFN * QUANTUM) + + +/* xopen -- allocate and open an XFILE +** +** NB: currently I'm designing these for READ-ONLY TEXT FILES only: the xopen +** interface may have to be changed... +** +** returns pointer to XFILE of opened file or null pointer on error +** +** ? should it leave a better error description somewhere ? +*/ + +XFILE *xopen(char const *name) +{ + XFILE *f = malloc(sizeof(XFILE) + XBUFSIZE + 1); + int n; + + if (f == 0) + goto error0; + f->buf = (char *)f + sizeof(XFILE); + + if ((f->fd = DOS_OPEN(name, O_RDONLY)) < 0) + goto error1; + + if ((n = READ(f->fd, f->buf, XBUFSIZE)) < 0) + goto error2; + + f->buf[n] = 0; + f->nextChar = f->buf; + return f; + +error2: + CLOSE(f->fd); +error1: + free(f); +error0: + return 0; +} + + +/* +** xclose -- close and deallocate an XFILE +*/ + +void xclose(XFILE *f) +{ + CLOSE(f->fd); + free(f); +} + + +/* +** xgetline -- get the next text line into memory +** +** returns a pointer to the line (a NUL-terminated string) or a null pointer +*/ + +char *xgetline(XFILE *f) +{ + char *s = f->nextChar, *p; + int n; + + for (p = s; *p != 0; ++p) + { + if (*p == '\n') + { + if (s < p && p[-1] == '\r') + p[-1] = 0; + else *p = 0; + f->nextChar = p + 1; + return s; + } + } + + /* + ** end of line not found in buffer -- p points to the sentinel NUL + */ + + if (p == f->buf) /* iff empty, EOF */ + return 0; + + /* + ** move prefix of line to bottom of buffer + */ + + if (s != f->buf) + { + for (p = f->buf; (*p = *s) != 0; ++p, ++s) + ; + s = f->buf; + } + + n = XBUFSIZE - (p - f->buf); + + if (n < QUANTUM) /* insufficent room, break line */ + { + f->nextChar = p; + return s; + } + + n = (n / QUANTUM) * QUANTUM; /* quantize: count to read */ + n = READ(f->fd, p, n); + + /* + ** read error is sort of ignored here... same return as EOF. + ** we'll see if this proves to be sufficent... + */ + + if (n < 0) + { + f->nextChar = f->buf; + f->buf[0] = 0; + return 0; + } + + p[n] = 0; + + for ( ; *p != 0; ++p) + { + if (*p == '\n') + { + if (s < p && p[-1] == '\r') + p[-1] = 0; + else *p = 0; + ++p; + break; + } + } + + f->nextChar = p; + return p == s ? 0 : s; +} diff --git a/reference/C/CONTRIB/SNIP/xfile.h b/reference/C/CONTRIB/SNIP/xfile.h new file mode 100755 index 0000000..afebe3f --- /dev/null +++ b/reference/C/CONTRIB/SNIP/xfile.h @@ -0,0 +1,41 @@ +/* +** xfile.h -- definitions for fast line buffered files +*/ + +#ifndef __XFILE_H__ +#define __XFILE_H__ + +struct _xfile { + int fd; + int bufSize; + char *buf; + char *nextChar; + char *lastChar; +}; + +typedef struct _xfile XFILE; + +#include <dos.h> + +#if defined(__ZTC__) + #include <io.h> + #define DOS_OPEN dos_open + #define READ read + #define CLOSE close +#elif defined(__TURBOC__) + #include <io.h> + #include <fcntl.h> + #define DOS_OPEN _open + #define READ _read + #define CLOSE _close +#else /* MSC */ + #include <stdlib.h> + #include <fcntl.h> + #define CLOSE _dos_close +#endif + +XFILE *xopen(char const *); +void xclose(XFILE *); +char *xgetline(XFILE *); + +#endif /* __XFILE_H__ */ diff --git a/reference/C/CONTRIB/SNIP/xstrcat.c b/reference/C/CONTRIB/SNIP/xstrcat.c new file mode 100755 index 0000000..a1bce5b --- /dev/null +++ b/reference/C/CONTRIB/SNIP/xstrcat.c @@ -0,0 +1,32 @@ +/* +** XSTRCAT.C - String concatenation function +** +** Notes: 1st argument must be a buffer large enough to contain the +** concatenated strings. +** +** 2nd thru nth arguments are the string to concatenate. +** +** (n+1)th argument must be NULL to terminate the list. +*/ + +#include <stdarg.h> + +char *xstrcat(char *des, char *src, ...) +{ + char *destination = des; + va_list v; + + va_start(v, src); + + while (src != 0) + { + while (*src != 0) + *des++ = *src++; + src = va_arg(v, char *); + } + *des = 0; + + va_end(v); + + return destination; +} diff --git a/reference/C/CONTRIB/SNIP/xstrcmp.c b/reference/C/CONTRIB/SNIP/xstrcmp.c new file mode 100755 index 0000000..3d9502c --- /dev/null +++ b/reference/C/CONTRIB/SNIP/xstrcmp.c @@ -0,0 +1,67 @@ +/* +** xstrcmp() - compares strings using DOS wildcards +** 'mask' may contain '*' and '?' +** returns 1 if 's' matches 'mask', otherwise 0 +** public domain by Steffen Offermann 1991 +*/ + + +int xstrcmp (char *mask, char *s) +{ + while (*mask) + { + switch (*mask) + { + case '?': + if (!*s) + return (0); + s++; + mask++; + break; + + case '*': + while (*mask == '*') + mask++; + if (!*mask) + return ( 1 ); + if (*mask == '?') + break; + while (*s != *mask) + { + if (!*s) + return (0); + s++; + } + s++; + mask++; + break; + + default: + if (*s != *mask) + return (0); + s++; + mask++; + } + } + + if (!*s && *mask) + return (0); + return ( 1 ); +} + +#ifdef TEST + +#include <stdio.h> + +void main(int argc, char *argv[]) +{ + if (3 != argc) + { + puts("Usage: XSTRCMP string_1 string_2"); + return; + } + printf("xstrcmp(\"%s\", \"%s\") returned %d\n", argv[1], argv[2], + xstrcmp(argv[1], argv[2])); +} + +#endif /* TEST */ diff --git a/reference/C/CONTRIB/SNIP/xtest.c b/reference/C/CONTRIB/SNIP/xtest.c new file mode 100755 index 0000000..7a22074 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/xtest.c @@ -0,0 +1,35 @@ +#include <stdio.h> +#include "xfile.h" + + +int main(int argc, char **argv) +{ + while (*++argv != 0) + { + XFILE *f = xopen(*argv); + + if (f == 0) + fprintf(stderr, "ERROR: can't open file %s\n", *argv); + else + { +#if 0 + char *s; + + fprintf(stdout, "--- %s ---\n", *argv); + while ((s = xgetline(f)) != 0) + fputs(s, stdout); + xclose(f); +#else + unsigned int nLines = 0; + char *s; + + while ((s = xgetline(f)) != 0) + ++nLines; + printf("%5u lines in %s\n", nLines, *argv); + xclose(f); +#endif + } + } + + return 0; +} diff --git a/reference/C/CONTRIB/YABL/Makefile.am b/reference/C/CONTRIB/YABL/Makefile.am new file mode 100644 index 0000000..b3c4d28 --- /dev/null +++ b/reference/C/CONTRIB/YABL/Makefile.am @@ -0,0 +1,5 @@ +EXTRA_DIST = yabl +docs_DATA = $(EXTRA_DIST) + +docsdir = $(kde_htmldir)/en/kdevelop/$(subdir) + diff --git a/reference/C/CONTRIB/YABL/Makefile.in b/reference/C/CONTRIB/YABL/Makefile.in new file mode 100644 index 0000000..b366330 --- /dev/null +++ b/reference/C/CONTRIB/YABL/Makefile.in @@ -0,0 +1,405 @@ +# KDE tags expanded automatically by am_edit - $Revision: 1.2 $ +# Makefile.in generated automatically by automake 1.5 from Makefile.am. + +# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +# Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = ../../../.. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_HEADER = $(INSTALL_DATA) +transform = @program_transform_name@ +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_alias = @build_alias@ +build_triplet = @build@ +host_alias = @host_alias@ +host_triplet = @host@ +target_alias = @target_alias@ +target_triplet = @target@ +AMTAR = @AMTAR@ +ARTSCCONFIG = @ARTSCCONFIG@ +AS = @AS@ +AUTODIRS = @AUTODIRS@ +AWK = @AWK@ +CC = @CC@ +CONF_FILES = @CONF_FILES@ +CPP = @CPP@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +DCOPIDL = @DCOPIDL@ +DCOPIDL2CPP = @DCOPIDL2CPP@ +DCOP_DEPENDENCIES = @DCOP_DEPENDENCIES@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DPMSINC = @DPMSINC@ +DPMSLIB = @DPMSLIB@ +EXEEXT = @EXEEXT@ +GCJ = @GCJ@ +GCJFLAGS = @GCJFLAGS@ +GLINC = @GLINC@ +GLLIB = @GLLIB@ +GMSGFMT = @GMSGFMT@ +IDL = @IDL@ +IDL_DEPENDENCIES = @IDL_DEPENDENCIES@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +JAR = @JAR@ +JAVAC = @JAVAC@ +JAVAH = @JAVAH@ +JVMLIBS = @JVMLIBS@ +KDECONFIG = @KDECONFIG@ +KDE_CXXFLAGS = @KDE_CXXFLAGS@ +KDE_EXTRA_RPATH = @KDE_EXTRA_RPATH@ +KDE_INCLUDES = @KDE_INCLUDES@ +KDE_LDFLAGS = @KDE_LDFLAGS@ +KDE_PLUGIN = @KDE_PLUGIN@ +KDE_RPATH = @KDE_RPATH@ +KDE_USE_CLOSURE_FALSE = @KDE_USE_CLOSURE_FALSE@ +KDE_USE_CLOSURE_TRUE = @KDE_USE_CLOSURE_TRUE@ +KDE_USE_FINAL_FALSE = @KDE_USE_FINAL_FALSE@ +KDE_USE_FINAL_TRUE = @KDE_USE_FINAL_TRUE@ +KDE_XSL_STYLESHEET = @KDE_XSL_STYLESHEET@ +LIBCOMPAT = @LIBCOMPAT@ +LIBCRYPT = @LIBCRYPT@ +LIBDL = @LIBDL@ +LIBGEN = @LIBGEN@ +LIBJPEG = @LIBJPEG@ +LIBMICO = @LIBMICO@ +LIBOBJS = @LIBOBJS@ +LIBPNG = @LIBPNG@ +LIBPTHREAD = @LIBPTHREAD@ +LIBPYTHON = @LIBPYTHON@ +LIBQIMGIO = @LIBQIMGIO@ +LIBRESOLV = @LIBRESOLV@ +LIBSHADOW = @LIBSHADOW@ +LIBSM = @LIBSM@ +LIBSOCKET = @LIBSOCKET@ +LIBTIFF = @LIBTIFF@ +LIBTOOL = @LIBTOOL@ +LIBUCB = @LIBUCB@ +LIBUTIL = @LIBUTIL@ +LIBXINERAMA = @LIBXINERAMA@ +LIBZ = @LIBZ@ +LIB_KAB = @LIB_KAB@ +LIB_KDECORE = @LIB_KDECORE@ +LIB_KDEUI = @LIB_KDEUI@ +LIB_KFILE = @LIB_KFILE@ +LIB_KFM = @LIB_KFM@ +LIB_KFORMULA = @LIB_KFORMULA@ +LIB_KHTML = @LIB_KHTML@ +LIB_KIMGIO = @LIB_KIMGIO@ +LIB_KIO = @LIB_KIO@ +LIB_KPARTS = @LIB_KPARTS@ +LIB_KSPELL = @LIB_KSPELL@ +LIB_KSYCOCA = @LIB_KSYCOCA@ +LIB_KWRITE = @LIB_KWRITE@ +LIB_QT = @LIB_QT@ +LIB_SMB = @LIB_SMB@ +LIB_X11 = @LIB_X11@ +LN_S = @LN_S@ +MCOPIDL = @MCOPIDL@ +MEINPROC = @MEINPROC@ +MICO_INCLUDES = @MICO_INCLUDES@ +MICO_LDFLAGS = @MICO_LDFLAGS@ +MOC = @MOC@ +MSGFMT = @MSGFMT@ +NOOPT_CXXFLAGS = @NOOPT_CXXFLAGS@ +NOREPO = @NOREPO@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PAMLIBS = @PAMLIBS@ +PASSWDLIBS = @PASSWDLIBS@ +PYTHONINC = @PYTHONINC@ +PYTHONLIB = @PYTHONLIB@ +PYTHONMODDIR = @PYTHONMODDIR@ +QT_INCLUDES = @QT_INCLUDES@ +QT_LDFLAGS = @QT_LDFLAGS@ +RANLIB = @RANLIB@ +REPO = @REPO@ +SETUIDFLAGS = @SETUIDFLAGS@ +STRIP = @STRIP@ +TOPSUBDIRS = @TOPSUBDIRS@ +UIC = @UIC@ +UIC_TR = @UIC_TR@ +USER_INCLUDES = @USER_INCLUDES@ +USER_LDFLAGS = @USER_LDFLAGS@ +USE_EXCEPTIONS = @USE_EXCEPTIONS@ +USE_RTTI = @USE_RTTI@ +USE_THREADS = @USE_THREADS@ +VERSION = @VERSION@ +XGETTEXT = @XGETTEXT@ +XPMINC = @XPMINC@ +XPMLIB = @XPMLIB@ +X_EXTRA_LIBS = @X_EXTRA_LIBS@ +X_INCLUDES = @X_INCLUDES@ +X_LDFLAGS = @X_LDFLAGS@ +X_PRE_LIBS = @X_PRE_LIBS@ +all_includes = @all_includes@ +all_libraries = @all_libraries@ +am__include = @am__include@ +am__quote = @am__quote@ +idldir = @idldir@ +install_sh = @install_sh@ +jni_includes = @jni_includes@ +kde_appsdir = @kde_appsdir@ +kde_bindir = @kde_bindir@ +kde_confdir = @kde_confdir@ +kde_datadir = @kde_datadir@ +kde_htmldir = @kde_htmldir@ +kde_icondir = @kde_icondir@ +kde_includes = @kde_includes@ +kde_libraries = @kde_libraries@ +kde_libs_htmldir = @kde_libs_htmldir@ +kde_libs_prefix = @kde_libs_prefix@ +kde_locale = @kde_locale@ +kde_mimedir = @kde_mimedir@ +kde_moduledir = @kde_moduledir@ +kde_qtver = @kde_qtver@ +kde_servicesdir = @kde_servicesdir@ +kde_servicetypesdir = @kde_servicetypesdir@ +kde_sounddir = @kde_sounddir@ +kde_templatesdir = @kde_templatesdir@ +kde_wallpaperdir = @kde_wallpaperdir@ +micodir = @micodir@ +qt_includes = @qt_includes@ +qt_libraries = @qt_libraries@ +x_includes = @x_includes@ +x_libraries = @x_libraries@ + +EXTRA_DIST = yabl +docs_DATA = $(EXTRA_DIST) + +docsdir = $(kde_htmldir)/en/kdevelop/$(subdir) +subdir = reference/C/CONTRIB/YABL +mkinstalldirs = $(SHELL) $(top_srcdir)/admin/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +DIST_SOURCES = +DATA = $(docs_DATA) + +DIST_COMMON = Makefile.am Makefile.in +#>- all: all-am +#>+ 1 +all: docs-am all-am + +.SUFFIXES: + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) +#>- cd $(top_srcdir) && \ +#>- $(AUTOMAKE) --gnu reference/C/CONTRIB/YABL/Makefile +#>+ 3 + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu reference/C/CONTRIB/YABL/Makefile + cd $(top_srcdir) && perl admin/am_edit reference/C/CONTRIB/YABL/Makefile.in +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) && \ + CONFIG_HEADERS= CONFIG_LINKS= \ + CONFIG_FILES=$(subdir)/$@ $(SHELL) ./config.status +uninstall-info-am: +install-docsDATA: $(docs_DATA) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(docsdir) + @list='$(docs_DATA)'; for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + f="`echo $$p | sed -e 's|^.*/||'`"; \ + echo " $(INSTALL_DATA) $$d$$p $(DESTDIR)$(docsdir)/$$f"; \ + $(INSTALL_DATA) $$d$$p $(DESTDIR)$(docsdir)/$$f; \ + done + +uninstall-docsDATA: + @$(NORMAL_UNINSTALL) + @list='$(docs_DATA)'; for p in $$list; do \ + f="`echo $$p | sed -e 's|^.*/||'`"; \ + echo " rm -f $(DESTDIR)$(docsdir)/$$f"; \ + rm -f $(DESTDIR)$(docsdir)/$$f; \ + done +tags: TAGS +TAGS: + + +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) + +top_distdir = ../../../.. +distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + if test -f $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + $(mkinstalldirs) "$(distdir)/$$dir"; \ + fi; \ + if test -d $$d/$$file; then \ + cp -pR $$d/$$file $(distdir) \ + || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(DATA) + +installdirs: + $(mkinstalldirs) $(DESTDIR)$(docsdir) + +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) stamp-h stamp-h[0-9]* + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +#>- clean: clean-am +#>+ 1 +clean: kde-rpo-clean clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + +distclean-am: clean-am distclean-generic distclean-libtool + +dvi: dvi-am + +dvi-am: + +info: info-am + +info-am: + +install-data-am: install-docsDATA + +install-exec-am: + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +uninstall-am: uninstall-docsDATA uninstall-info-am + +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + distclean distclean-generic distclean-libtool distdir dvi \ + dvi-am info info-am install install-am install-data \ + install-data-am install-docsDATA install-exec install-exec-am \ + install-info install-info-am install-man install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool uninstall uninstall-am uninstall-docsDATA \ + uninstall-info-am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: + +#>+ 2 +docs-am: + +#>+ 6 +force-reedit: + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu reference/C/CONTRIB/YABL/Makefile + cd $(top_srcdir) && perl admin/am_edit reference/C/CONTRIB/YABL/Makefile.in + + +#>+ 2 +final: + $(MAKE) all-am +#>+ 2 +final-install: + $(MAKE) install-am +#>+ 2 +no-final: + $(MAKE) all-am +#>+ 2 +no-final-install: + $(MAKE) install-am +#>+ 3 +cvs-clean: + $(MAKE) -f $(top_srcdir)/admin/Makefile.common cvs-clean + +#>+ 3 +kde-rpo-clean: + -rm -f *.rpo diff --git a/reference/C/CONTRIB/YABL/yabl b/reference/C/CONTRIB/YABL/yabl new file mode 100644 index 0000000..6aa68ac --- /dev/null +++ b/reference/C/CONTRIB/YABL/yabl @@ -0,0 +1,3161 @@ +TITLE: *** YABL *** +AUTHOR: Mitch Wright +AUTHOR: Fellow USENET Readers... +DATE: Tue Dec 7 11:53:54 PST 1993 +COMMENTS + For complaints, kudos, suggestions, corrections, additions, donations, ... + drop me an E-mail note -- mitch@oz.com. + + The latest version of this list can be obtained via anonymous ftp from + + ftp.rahul.net pub/mitch/YABL/yabl + +TITLE: !%@:: A Guide to Electronic Mail Addressing, 2nd edition +AUTHOR: Frey, Donnalyn +AUTHOR: Adams, Rick +SUBJECT: Introduction +PUBLISHER: O'Reilly & Associates, Inc. +DATE: 1993 +PAGES: 458 +ISBN: 0-56592-03107 +APPROX_COST: $24.95 +KEYWORDS: e-mail +COMMENTS + Answers the problem of addressing mail to people you've never met, on + networks you've never heard of. Includes a general introduction to + e-mail, followed by detailed reference sections for over 130 networks. + ** This has been completely updated since the 1990 version!!! ** + + Topics covered include: + + * An introduction to e-mail for beginners + * For over 180 networks: a description of the network, the + services it provides, the format of the e-mail addresses + needed to reach users on that network + * Index to networks by network name, country or area name, + and country code + * Index to second and third level domains and many sites + within each network + +TITLE: ANSI C Card +AUTHOR: SSC Staff +SUBJECT: Pocket-sized reference card on the ANSI C language +PUBLISHER: SSC (Specialized Systems Consultants, Inc.) +DATE: June, 1991 (revised) +PAGES: 8 +ISBN: 0-916151-48-4 +APPROX_COST: $3.00 +KEYWORDS: ANSI C, pocket reference +SUGGESTED_BY: Phil Hughes fyl@ssc.wa.com +COMMENTS + Includes constants, variables, functions, statements, + proprocessor directives, common I/O functions, formatted I/O, + ASCII chart. Operator precidence chart. + +TITLE: The AWK Programming Language +AUTHOR: Aho, Al +AUTHOR: Kernighan, Brian +AUTHOR: Weinberger, Peter +SUBJECT: AWK Programming +PUBLISHER: Addison Wesley +DATE: 1988 +PAGES: 210 +ISBN: 0-201-07981-X +LC: 87-17566 +APPROX_COST: 23.75 + +TITLE: Algorithms in C +AUTHOR: Sedgewick, Robert +PUBLISHER: Addison-Wesley +DATE: 1990 +PAGES: <pages> +ISBN: 0-201-51425-7 +APPROX_COST: <$$.cc> +SUGGESTED_BY: "Diomidis Spinellis" <dds@doc.ic.ac.uk> +COMMENTS + Many useful algorightms expressed in C + +TITLE: The Art of Distributed Appl., Programming Techniques for RPC +AUTHOR: Corbin, John R. +PUBLISHER: Springer-Verlag (Part of Sun Techincal Reference Library) +DATE: 1991 +PAGES: 558 +ISBN: 0-387-97247-1 +APPROX_Cost: 39.95 +SUGGESTED_BY: "Betty Jo Armstead, Sverdrup" <xxbja@csduts1.lerc.nasa.gov> +COMMENTS + An excellent book for anyone starting to develop RPC applications.his + The book covers SUN style RPC programming with lots of examples. the + It covers XDR, RPC Protocol, RPC programming, Low-level RPC + Programming, Additional RPC Library Features, RPCGEN, Developing + RPC-based Distributed Applications and the future of RPC + programming. The books also hints at multithreaded RPC + applications, but provides no examples and very little discussion + on this topic. + +TITLE: Advanced C Programming for Displays +AUTHOR: Rochkind, Marc J. +SUBJECT: Programming +PUBLISHER: Prentice-Hall +DATE: 1988 +PAGES: 331 +ISBN: 0-13-010240-07 +APPROX_COST: 32.95 +SUGGESTED_BY: "Michael J. Chinni, SMCAR-CCS-E" <mchinni@PICA.ARMY.MIL> +COMMENTS + Covers Character Displays, Windows, and Keyboards for UNIX and MS-DOS. + +TITLE: Advanced UNIX Programming +AUTHOR: Rochkind, Marc J. +SUBJECT: Programming +PUBLISHER: Prentice-Hall +EDITION: 1985, pp 265 +ISBN: 0-13-011818-4 HBK +ISBN: 0-13-011800-1 PBK +APPROX_COST: 32.95 HBK +APPROX_COST: 24.95 PBK +KEYWORDS: SYSV +COMMENTS + Rochkind is a former Bell Labs UNIX guru who wrote SCCS back in the + mid 70's. This book is exactly what the title states, basically an + extremely thorough treatment of programming using the UNIX System + Call Interface. System V, System III, V7, 4.2 BSD, and Xenix are + all discussed. The system calls are organized functionally into + chapters that cover file i/o, terminal i/o, process control, + interprocess communication, and miscellaneous calls. The opening + chapter is an overvview of fundamental concepts of UNIX. Anytime + I have a question on the usage of system calls I consult this book. + The only problem with it is that it needs to be updated per + System V Rel 3, 4.3 BSD and the efforts of Sun and AT&T to bring + SunOS and System V together as well as the efforts in the UNIX 386 + world. + +TITLE: Advanced UNIX: A Programmer's Guide +AUTHOR: Prata, Stephen +SUBJECT: Programming Guide +PUBLISHER: Howard W. Sams & Co. +DATE: 1985 +PAGES: 484 +ISBN: 0-067-22403-8. +APPROX_COST: 24.95 +KEYWORDS: SYSV +COMMENTS + Prata assumes you know how to login and use an editor. It's very + good for shell programing. + +TITLE: The Art of Computer Programming (V1), Fundamental Algorithms +AUTHOR: Knuth, Donald E. +PUBLISHER: Addison-Wesley +DATE: 1973 +ISBN: <isbn> +PAGES: <pages> +APPROX_COST: <$$.cc> +KEYWORDS: Algorithms + +TITLE: The Art of Computer Programming (V2), Seminumerical Algorithms +AUTHOR: Knuth, Donald E. +PUBLISHER: Addison-Wesley +DATE: 1981 +ISBN: 0-201-03822-6 +PAGES: <pages> +APPROX_COST: <$$.cc> +KEYWORDS: Algorithms + +TITLE: The Art of Computer Programming (V3), Sorting and Searching +AUTHOR: Knuth, Donald E. +PUBLISHER: Addison-Wesley +DATE: 1973 +ISBN: 0-201-03803-X +PAGES: <pages> +APPROX_COST: <$$.cc> +KEYWORDS: Algorithms + +TITLE: BSD 4.3 Manual Set +AUTHOR: University of California Berkeley +SUBJECT: 4.3 BSD UNIX Operating System +DATE: June 1988 +PAGES: <lots> +ISBN: <unknown> +APPROX_COST: 60.00/set +SUGGESTED_BY: An anonymous BSD zealot +COMMENTS + This is a must for programmers, administrator, and users alike. + If you are in contact with the BSD UNIX Operating system, YOU + need these manuals! Kudos to the boys at Cory and Evans! + *Printed by the USENIX Association as a service to the UNIX Comm. + +TITLE: Beginning UNIX Commands +AUTHOR: SSC Staff +SUBJECT: Pocket-sized reference card on basic UNIX System commands +PUBLISHER: SSC (Specialized Systems Consultants, Inc.) +DATE: January, 1992 (revised) +PAGES: 4 +ISBN: 0-916151-55-7 +APPROX_COST: FREE with order of send #10 SASE +KEYWORDS: UNIX, pocket reference +SUGGESTED_BY: Phil Hughes fyl@ssc.wa.com +COMMENTS + Lists 30 generic UNIX commands with examples of usage. + +TITLE: The Berkeley UNIX Environment +AUTHOR: Horspool, R. Nigel +SUBJECT: C Programming, BSD Unix +PUBLISHER: Prentice Hall +DATE: 1992 +PAGES: 379 +ISBN: 0-13-089368-4 +APPROX_COST: 30.00 +KEYWORDS: BSD, C +SUGGESTED_BY: Chet Creider <creider@taptet.sscl.uwo.ca> +COMMENTS + An excellent introduction to workstation use. Sections on + vi, Gnu emacs, csh (including C shell programming), lex, yacc, + systems programming in C (5 chapters), make, SCCS, RCS, dbx, + and much more. + +TITLE: A Book on C +AUTHOR: Kelley, Al +AUTHOR: Pohl, Ira +SUBJECT: C Programming +PUBLISHER: Benjamin/Cummings Publishing Company, Inc. +DATE: 1984 +PAGES: 362 +ISBN: 0-8053-6860-4 +APPROX_COST: 32.25 +SUGGESTED_BY: Mitch Wright <mitch@hq.af.mil> +COMMENTS + This is a book written with the beginning C programmer in mind. + +TITLE: Checking C Programs with lint +AUTHOR: Darwin, Ian F. +SUBJECT: lint +PUBLISHER: O'Reilly & Associates +DATE: 1990 +PAGES: 84 +ISBN: 0-937175-30-7 +APPROX_COST: 12.95 +KEYWORDS: lint, C, nutshell +COMMENTS: + The lint program checker has proven itself time and again to be + one of the best tools for finding portability problems and + certain types of coding errors in C programs. This book + introduces you to lint, guides you through running it on your + programs and helps you to interpret lint's output. + +TITLE: The C Answer Book +AUTHOR: Tondo, Clovis L. +AUTHOR: Gimpel, Scott E. +SUBJECT: C programming +PUBLISHER: Prentice-Hall +DATE: 1989 +PAGES: 208 +ISBN: 0-13-109877-2 +APPROX_COST: 30.00 +KEYWORDS: K&R answers +COMMENTS + This book provides the answers to the exercises found in K&R. I + believe that a second edition of this book has also been recently + published corresponding with the 2nd edition of K&R. + +TITLE: C Language for Programmers, 2nd ed. +AUTHOR: Pugh, Kenneth +SUBJECT: C Programming +PUBLISHING: QED Information Sciences +DATE: 1989 +PAGES: 320 +ISBN: 0-89435-367-5 +APPROX_COST: $29.95 +KEYWORDS: C, tutorial +COMMENTS: Teaches non-C programmers how to code in C + +TITLE: C Library Reference +AUTHOR: SSC Staff +SUBJECT: Pocket-sized reference on the C library +PUBLISHER: SSC (Specialized Systems Consultants, Inc.) +DATE: 1985 +PAGES: 33 +ISBN: 0-916151-11-5 +APPROX_COST: $6.00 +KEYWORDS: C library, pocket reference +SUGGESTED_BY: Phil Hughes fyl@ssc.wa.com +COMMENTS + Documents the UNIX System 5.2 C library. Includes index + to UNIX man pages. The cover is a condensed explanation + of the C language. + +TITLE: C Pointers and Dynamic Memory Management +AUTHOR: Daconta, Michael C. +SUBJECT: C Pointers, Mem Management, Traps +PUBLISHER: QED Publishing +DATE: 1993 +PAGES: 340 +ISBN: 0-89435-473-6 +APPROX_COST: 39.95 +SUGGESTED_BY: Roger Smith <smith@source.asset.com> +KEYWORDS: C Programming, pointers, memory management, data structures +COMMENTS + Saves lots of time using some of the parser code. Cements pointer + and memory management concepts. Good diagrams and plenty of examples. + Lots of other stuff explained well: pointer pointers, function + pointers, pointer traps, memory debugger ... highly recommend for + a C programmers bookshelf! + +TITLE: C Primer Plus Revised Edition +AUTHOR: Waite, Mitchell +AUTHOR: Prata, Stephen +AUTHOR: Martin, Donald +SUBJECT: C programming +PUBLISHER: Howard W. Samms & Company +DATE: 1987 +PAGES: 558 +ISBN: 0-672-22582-4 +APPROX_COST: 23.95 +SUGGESTED_BY: "Michael J. Chinni, SMCAR-CCS-E" <mchinni@PICA.ARMY.MIL> +COMMENTS + An excellent beginners guide to C programming. I found out about this + book through a vendor's training class on C, where they used it as the + textbook. + +TITLE: C Programming Guide, 3rd Ed. +AUTHOR: Purdum, J.J. +SUBJECT: C Programming +PUBLISHER: Que Corporation +DATE: 1988 +PAGES: 456 +ISBN: 0-88022-356-1 +LCCN: 88-61496 +OCLC: 18865012 + +TITLE: The C Programmer's Handbook +AUTHOR: Bolsky, Morris I. +SUBJECT: Reference +PUBLISHER: Prentice-Hall +DATE: 1985 +PAGES: 84 +ISBN: 0-13-110073-4 +APPROX_COST: 22.95 +KEYWORDS: C Programming +COMMENTS + This is a handbook for experience programmers, not a book for reading. + Information is intended as a quickie reference and is not that + detailed. + +TITLE: The C Programming Language, First Edition +AUTHOR: Kernigan, Brian W. +AUTHOR: Ritchie, Dennis M. +SUBJECT: C Programming +PUBLISHER: Prentice-Hall +DATE: 1978 +PAGES: 228 +ISBN: 0-13-110163-3 +APPROX_COST: 27.00 +KEYWORDS: C, UNIX, K&R C +SUGGESTED_BY: Mitch Wright <mitch@hq.af.mil> +COMMENTS + ** The Original Bible of C programming ** + "... a book that ocntains a tutorial introduction to get new userss + started as soon as possible, separate chapters on major features + and a reference manual" + +TITLE: The C Programming Language, Second Edition +AUTHOR: Kernigan, Brian W. +AUTHOR: Ritchie, Dennis M. +SUBJECT: C Programming +PUBLISHER: Prentice-Hall +DATE: 1988 +PAGES: 272 +ISBN: 0-13-110362-8 +APPROX_COST: 28.00 +SUGGESTED_BY: "Michael J. Chinni, SMCAR-CCS-E" <mchinni@PICA.ARMY.MIL> +COMMENTS + The Bible of C programming + +TITLE: C Programmer's Library, 2nd Ed. +AUTHOR: Purdum, J.J. +SUBJECT: C language +PUBLISHER: Que Corporation +DATE: 1985 +PAGES: 319 +ISBN: 0-88022-157-7 +LCCN: 85-60689 +OCLC: 12819701 + +TITLE: C Programmer's Toolkit +AUTHOR: Purdum, Jack J. +SUBJECT: C language +PUBLISHER: Que Corporation +DATE: 1989 +PAGES: 350 +ISBN: 0-88022-457-6 +LCCN: 89-61069 +OCLC: 21130331 + +TITLE: The C Puzzle Book: Puzzles for the C Programming Language, 2nd Ed. +AUTHOR: Feuer, Alan R. +SUBJECT: C programming +PUBLISHER: Prentice-Hall +DATE: 1982 +PAGES: 173 +ISBN: 0-13-109934-5 HBK +ISBN: 0-13-109926-4 PBK +APPROX_COST: 26.00 +COMMENTS + Exactly what the title indicates. The puzzles are organized by + chapter: basic arithmetic operators, assignment operators, logic and + increment operators, bitwise operators, relational and conditional + operators, operator precedence and evaluation. The answers for all of + the puzzles are also provided. This is an excellent way to learn some + of the more advanced expressions that can be concocted with C. + +TITLE: C Self-Study Guide +AUTHOR: Purdum, J.J. +SUBJECT: C language +PUBLISHER: Que Corporation +DATE: 1985 +PAGES: 249 +ISBN: 0-88022-149-6 +OCLC: 12790605 +B-NO: 411153F + +TITLE: C Standard Library +AUTHOR: Purdum, Jack J. +AUTHOR: Leslie, Timothy C +SUBJECT: C language +PUBLISHER: Que Corporation +DATE: 1987 +PAGES: 437 +ISBN: 0-88022-279-4 +LCCN: 86-62528 +OCLC: 16411542 + +TITLE: C Traps and Pitfalls +AUTHOR: Koenig, Andrew +SUBJECT: C programming +PUBLISHER: Addison-Wesley +DATE: 1988 +PAGES: 147 +ISBN: 0-201-17928-8 +APPROX_COST: 17.50 +COMMENTS + Andrew published a BTL Technical Memorandum by this title several + years back. Later it was published as a Technical Report. It has now + been expanded into a book. I read the TR and it was excellent. I + just recently finished the book and would recommend it to anyone who + uses C. + +TITLE: The C and Unix Dictionary +AUTHOR: Christian, Kaare +SUBJECT: Definitions of terms +PUBLISHER: John Wiley & Sons, Inc. +DATE: 1988 +PAGES: 216 +ISBN: 0-471-60929-3 HBK +ISBN: 0-471-60931-5 PBK +APPROX_COST: 24.95 +COMMENTS + Definitions of over 1000 terms in the C and Unix lexicon. + +TITLE: C: A Reference Manual, 2nd Edition +AUTHOR: Harbison, Samuel P. +AUTHOR: Steele Jr., Guy L. +SUBJECT: C Programming +PUBLISHER: Prentice-Hall +DATE: 1987 +PAGES: 404 +ISBN: 0-13-109810-1 HBK +ISBN: 0-13-109802-0 PBK +APPROX_COST: 31.95 +COMMENTS + An excellent book on C. It is not really an introductory level book, + and is a great companion to K&R (2nd Ed.). Both this book and K&R + (2nd Ed.) cover the draft-proposed ANSI standards. Where H&S really + stands out is in the sections that cover the UNIX library calls. If + you have ever struggled with any of printf or scanf family of library + calls in trying to figure out the conversion rules in the format + string, this book is the answer. + +TITLE: Compiler Design in C +AUTHOR: Holub, Allen I. +SUBJECT: Compiler Design +PUBLISHER: Prentice-Hall +DATE: 1990 +PAGES: 924 +ISBN:0-13-155045-4 +KEYWORDS: C Compilers, YACC +SUGGESTED_BY: Mitch Wright <mitch@oz.com> +COMMENTS + Great book! And lots of source examples to boot. + +TITLE: Compilers, Principles, Techniques, and Tools +AUTHOR: Aho, Alfred V. +AUTHOR: Sethi, Ravi +AUTHOR: Ullman, Jefferey D. +PUBLISHER: Addison-Wesley +DATE: 1985 +PAGES: <pages> +ISBN: 0-201-10088-6 +APPROX_COST: <$$.cc> +SUGGESTED_BY: "Diomidis Spinellis" <dds@doc.ic.ac.uk> +COMMENTS + Very good compile book. Covers yacc and lex theory and practice. + +TITLE: Computer Security Basics +AUTHOR: Russell, Deborah +AUTHOR: Gangemi Sr., G.T. +SUBJECT: Computer Security +PUBLISHER: O'Reilly and Associates +DATE: 1992 +PAGES: 464 +ISBN: 0-937175-71-4 +APPROX_COST: 29.95 +KEYWORDS: Security, UNIX +SUGGESTED_BY: "Cliff Stoll" <cliff@cfa.harvard.edu> +COMMENTS + For computer managers who use Orange Book sytems -- trusted + computer systems. A lot about government standards and what + it means to have a certified secure system. + +TITLE: Computers Under Attack +AUTHOR: Denning, Peter [editor] +PUBLISHER: ACM Press / Addison-Wesley Publishing Co. +DATE: 1990 +PAGES: 554 +ISBN: 0-201-53067-8 +APPROX_COST: 35.00 +SUGGESTED_BY: "Cliff Stoll" <cliff@cfa.harvard.edu> +COMMENTS + A collection of articles about computer security. + Good history of networks and an introduction to the internet, + with emphasis on security problems. Reviews of the internet + worm of 1988, computer viruses, and the nature of openness + in a networked community. + +TITLE: Computerization and Controversy +AUTHOR: Dunlop & Kling [editor] +PUBLISHER: Academic Press +DATE: 1991 +PAGES: 758 +ISBN: 0-12-224356-0 +APPROX_COST: 65.00 +SUGGESTED_BY: "Cliff Stoll" <cliff@cfa.harvard.edu> +COMMENTS + A splendid collection of articles on the social impact of + computers. Check out "The Strange Case of the Electronic + Lover" (from Ms. Magazine), or "Safety-Critical Computing" + or "Social Analysis of Computing". Technically solid and + socially important writing in here. + +TITLE: Connecting to the Internet +AUTHOR: Estrada, Susan +SUBJECT: Networking +PUBLISHER: O'Reilly & Associates +DATE: Aug 1993 +PAGES: 170 +ISBN: 1-56592-061-9 +APPROX_COST: +KEYWORDS: networking, internet + +TITLE: Cryptography and Data Security +AUTHOR: Denning, Dorothy E. +PUBLISHER: Addison-Wesley +DATE: 1983 +PAGES: <pages> +ISBN: 0-201-10150-5 +APPROX_COST: <$$.cc> +SUGGESTED_BY: "Diomidis Spinellis" <dds@doc.ic.ac.uk> +COMMENTS + Scientific treatment of cryptography and security. + +TITLE: The Cuckoo's Egg +AUTHOR: Stoll, Cliff +PUBLISHER: Pocketbooks, New York City +DATE: 1989, 1990 +PAGES: 356 +ISBN: 0-671-72688-9 +APPROX_Cost: Paperback - $5.95 (cheap at half the price) +HARDBACK: Doubleday, ISBN 0-385-24946-2, $20 (acid free!) +SUGGESTED_BY: "Cliff Stoll" <cliff@cfa.harvard.edu> [see disclaimer] +COMMENTS + This is the true story of catching a spy over the Internet. + + A hacker broke into a Berkeley astronomy computer, then + entered dozens of military computers through networks. + Here's how to catch a spy, without much help from the + FBI, the CIA, and the NSA. + + Six months on the NY Times best-seller list, + two weeks on the Usenet most-flamed about list. + + "A spy story for the 90's -- and it's all true!" - Tom Clancy + "A nonfiction book that reads like a Le Carre spy novel"- Seattle Times + "A gripping spy thriller" -- New York Times Book Review + "Indiana Jones & Tron, with a dash of Berkeley" -- William Press + "Fast-moving - read it straight through in one evening" -- Evelyn Leeper + "Not bad" - Cliff's Mom + + Disclaimer: I caught the hacker, wrote the book, and + stand to earn two bits if you buy a copy. - Cliff Stoll + +TITLE: Cyberpunk +AUTHOR: Hafner and Markoff +PUBLISHER: Simon and Schuster +DATE: 1991 +PAGES: 362 +ISBN: 0-671-68322-5 +APPROX_COST: 22.00 +SUGGESTED_BY: "Cliff Stoll" <cliff@cfa.harvard.edu> +COMMENTS + This book tells of the computing counterculture -- the + underground of computing. Three people who became known + for their exploits: Kevin Mitnick, who obsessively broke + into DEC systems in Southern California; Hans Hubner, who + was a part of the German group that stole American military + information and sold it to the KGB; and Robert T. Morris, + who wrote the Internet worm of 1988. Perhaps the title of + this book is misleading, but the subtitle isn't: Outlaws + and hackers on the Computer Frontier + +TITLE: The C++ Programming Language +AUTHOR: Stroustrup, Bjarne +PUBLISHER: Addison-Wesley +ISBN: 0-201-12078-X +PAGES: <pages> +APPROX_COST: <$$.cc> +SUGGESTED_BY: "Diomidis Spinellis" <dds@doc.ic.ac.uk> +COMMENTS + The standard C++ book. + +TITLE: A C++ Primer +AUTHOR: Lippman, Stanley B. +PUBLISHER: Addison-Wesley +DATE: 1989 +PAGES: <pages> +ISBN: 0-201-16487-6 +APPROX_COST: <$$.cc> +SUGGESTED_BY: "Diomidis Spinellis" <dds@doc.ic.ac.uk> +COMMENTS + A good introduction to C++ programming. + +TITLE: C++ Reference +AUTHOR: SSC Staff +SUBJECT: Pocket-sized reference card on C++ language, Version 2 +PUBLISHER: SSC (Specialized Systems Consultants, Inc.) +DATE: July, 1991 +PAGES: 16 +ISBN: 0-916151-49-2 +APPROX_COST: $4.50 +KEYWORDS: C++, pocket reference +SUGGESTED_BY: Phil Hughes fyl@ssc.wa.com + +TITLE: DNS and BIND +AUTHOR: Albitz, Paul +AUTHOR: Liu, Cricket +SUBJECT: DNS, BIND +PUBLISHER: O'Reilly and Associates +DATE: October 1992 +PAGES: 381 +ISBN: 1-56592-010-4 +APPROX_COST: $27.95 +KEYWORDS: Domain Name Service, DNS, BIND, named, resolve +SUGGESTED_BY: Mitch Wright <mitch@oz.com> +COMMENTS: + I'm just starting to read mine (got it today), and so far so + good. For the moment, let me leave you with an excerpt from + the cover: + + ``Whether you're an administrator involved with DNS on a daily + basis, or a user who wants to be mroe informed about the + internet and how it works, you'll find that this book is + essential reading.'' + + Topics include: + + . What DNS does, how it works, and when you need to use it + . How to find your own place in the Internet's name space + . Setting up name servers + . Using MX records to route mail + . Configuring hosts to use DNS name servers + . Subdividing domains (parenting) + . Long-term maintenance + . Troubleshooting: using nslookup, reading debug output, + and common problems + . Low-level programming with the resolver library + +TITLE: DOS Meets UNIX +AUTHOR: Dougherty, Dale +AUTHOR: O'Reilly, Tim +SUBJECT: Introduction +PUBLISHER: O'Reilly & Associates, Inc. +DATE: 1988 +PAGES: 148 +ISBN: 0-937175-21-8 +APPROX_COST: 15.00 +KEYWORDS: Nutshell Handbook +COMMENTS + Describes the solutions available for integrating DOS and UNIX. It + also briefly introduces UNIX for DOS users. + +TITLE: Data Structures and C Programs. +AUTHOR: Van Wyk, Christopher +SUBJECT: C programming +DATE: 1989 +PAGES: 387 +ISBN: 0-201161-16-8 +APPROX_COST: 41.95 +SUGGESTED_BY: srvarma@rodan.acs.syr.edu +KEYWORDS: C, Data Structures +COMMENTS + The author is from Bell Labs and this is also one of my favorite books + for learing C programming with different kinds of data structures." + [ *** NOTE: Has been reprinted with corrections *** ] + +TITLE: Data Structures and Program Design in C +AUTHOR: Kruse, Robert L. +AUTHOR: Leung, Bruce P. +AUTHOR: Tondo Clovis L. +SUBJECT: C Programming +PUBLISHER: Prentice Hall +DATE: 1991 +PAGES: 525 +ISBN: 0-13-725649-3 +APPROX_COST: 47.00 +KEYWORDS: C, Data Structures +COMMENTS: + From back cover: + This introduction to data structures using the C programming + language emphasizes problem specification and program design; + analysis, testing, and verification; and program correctness + +TITLE: The Design and Implementation of the 4.3BSD Unix Operating System +AUTHOR: Leffler, Samuel J. +AUTHOR: McKusick, Marshall Kirk +AUTHOR: Karels, Michael J. +AUTHOR: Quarterman, John S. +SUBJECT: Design of BSD UNIX +PUBLISHER: Addison-Wesley +DATE: 1989 +PAGES: 471 +ISBN: 0-201-06196-1 +APPROX_COST: 39.00 +KEYWORDS: Internals, Kernel, BSD +SUGGESTED_BY: Mitch Wright <mitch@hq.af.mil> +COMMENTS + These are the primary people who are responsible for 4.3 BSD. + + --From back cover-- + This book is the first authoritative description of the design and + implementation of the research version of the UNIX System developed + at the University of California at Berkeley. It covers the INTERNAL + structure of the 4.3BSD system and the concetps, data structures, and + algorithms used in implementing the system facilites. The book also + includes a chaper on the implementation of TCP/IP -- a networking + protocol suite widely implemented throughout the world. + + Both philosophical and design issues of 4.3BSD are discussed, as well + as details of the actual implementation. In most cases, the + discussion starts at the system-call level and descends from the + interface to the kernel down to the hardware itself. The kernel + includes system facilities such as process management, memory + management, the I/O system, the filesystem, the socket IPC mechanism, + and network-protocol implementations. + + The Design and Implemenation of the 4.3BSD UNIX Operating System is an + in-depth study of a contemporary operating system. This book assumes + that the reader understands basic operating-system terminology and has + some familiarity with any version of the UNIX System and with the C + programming language. Therefore, this book is suitable for + operating-system implementors, systems programmers, and UNIX + application developers. + +TITLE: The Design of the Unix Operating System +AUTHOR: Bach, Maurice J. +SUBJECT: Design of UNIX +PUBLISHER: Prentice-Hall +DATE: 1986 +PAGES: 471 +ISBN: 0-13-201799-7 +APPROX_COST: 47.20 +KEYWORDS: SYSV, AT&T +COMMENTS + A good generic introduction to kernel operation. (System V) + +TITLE: The Elements of Programming Style +AUTHOR: Kernighan, Brian W. +AUTHOR: Plauger, P. J. +PUBLISHER: McGraw-Hill +DATE: 1978 +PAGES: <pages> +ISBN: 0-07-034207-5 +APPROX_COST: <$$.cc> +SUGGESTED_BY: "Diomidis Spinellis" <dds@doc.ic.ac.uk> +COMMENTS + A very good book on style. Although dated, most of it is + still important and relevant. + +TITLE: Efficient C +AUTHOR: Plum, Thomas +AUTHOR: Brodie, Jim +SUBJECT: C programming +PUBLISHER: Plum Hall +DATE: 1985 +PAGES: 150 +ISBN: 0-911537-05-8 +APPROX_COST: 25.00 +COMMENTS + This is a useful book. Portability is one aspect of programming in C. + Efficiency is the other. Many use C because it allows them the + freedom to tie the programs down to the hardware in order to run + efficiently. This book is an excellent guide and when combined with + Jon Bentley's book on writting efficient programs gives one an + excellent background in measuring programs and fine tuning them. + +TITLE: Emacs Reference Card +AUTHOR: Dennis Gentry +SUBJECT: Pocket-sized reference card on the Gnu Emacs editor +PUBLISHER: SSC (Specialized Systems Consultants, Inc.) +DATE: August, 1992 +PAGES: 16 +ISBN: 0-916151-59-2 +APPROX_COST: $4.50 +KEYWORDS: Gnu, Emacs, pocket reference +SUGGESTED_BY: Phil Hughes fyl@ssc.wa.com + +TITLE: Essential System Administration +AUTHOR: Frisch, AEleen +SUBJECT: Administration +PUBLISHER: O'Reilly and Associates +DATE: 1992 +PAGES: 466 +ISBN: 0-937175-80-3 +APPROX_COST: 29.95 +KEYWORDS: System admin., SVR3, SVR4, SunOS, AIX, BSD, XENIX +COMMENTS + -From back cover- + Topics covered include: + . Starting your system and shutting it down + . Adding new users + . Managing UNIX processes + . Making the sytem secure + . Organizing and planning filesystems + . Planning and performing backups + . Restoring lost files from a backup tape + . Setting up a printer and the spooling system + . Overseeing a TCP/IP network (including NFS) + . Adding new terminals and disk drives + . Setting up and using the accounting system + + Essential System Administration covers all of the major versions + of UNIX, including BSD, Systems V.3 and V.4, SunOS, XENIX, and + AIX 3.1. + +TITLE: Exploring the UNIX system +AUTHOR: Kochan, Stephen G. +AUTHOR: Wood, Patrick H. +SUBJECT: Introduction to UNIX +PUBLISHER: Hayden Book Company +DATE: 1984 +PAGES: 370 +ISBN: 0-8104-6268-0 +APPROX_COST: 22.95 +SUGGESTED_BY: "Michael J. Chinni, SMCAR-CCS-E" <mchinni@PICA.ARMY.MIL> +KEYWORDS: Introduction +COMMENTS + A very good intro. book to UNIX. Has chapters on UNIX file system, + Bourne shell, vi, Program development, security, communications, and + administration. + +TITLE: GNU Emacs: UNIX Text Editing and Programming +AUTHOR: Schoonover, Michael +AUTHOR: Bowie, John +AUTHOR: Arnold, Bill +SUBJECT: GNU Emacs +PUBLISHER: Addison-Wesley / HP Press +DATE: 1991 +PAGES: 640 +ISBN: 0-201563-45-2 +APPROX_COST: 26.95 +KEYWORDS: Emacs, Editor, GNU +SUGGESTED_BY: Michael Schoonover <michael@hpfclw.fc.hp.com> +SUPPLIERS + Ordering info: 1-800-333-0088 +COMMENTS + . Examples, examples, examples. + + . Appendix on switching from vi to Emacs; has vi-to-Emacs + command mappings for all your favorite vi commands. + + . Separate chapters on general programming, C mode, Fortran + mode, and Lisp modes; also, an appendix on the non-standard + Pascal mode written by Vincent Broman. + + . Extensive chapter on customizing Emacs, with many examples. + + . Emacs-Lisp programming appendix (40 pages worth of info), + with examples of using common Emacs-Lisp functions. + + . Comprehensive command reference with commands and variables + grouped together by function, so you don't have to wade + through voluminous alphabetical lists of commands and + functions. In addition, the command reference refers you to + pages in the manual where detailed info is found. + + . Command summary at the end of each chapter. + + . Printed on recycled paper! + +TITLE: Guide to OSF/1: A Technical Synopsis +AUTHOR: Staff at O'Reilly & Associates +SUBJECT: OSF +PUBLISHER: O'Reilly and Associates +DATE: <year> +PAGES: 304 +ISBN: 0-937175-78-1 +APPROX_COST: 21.95 +KEYWORDS: OSF, Unix +COMMENTS: + This technically-competent introduction to OSF/1 is based on + OSF technical seminars. In addition to its description of + OSF/1, it includes the differences between OSF/1 and System V + Release 4, and a look ahead at DCE. + +TITLE: The New Hackers Dictionary +AUTHOR: Raymond, Eric +PUBLISHER: MIT Press +DATE: 1991 +PAGES: <pages> +ISBN: <isbn> +APPROX_COST: <$$.cc> +SUGGESTED_BY: "Diomidis Spinellis" <dds@doc.ic.ac.uk> +COMMENTS + A dictionary of most words, acronyms and slang used by people + using computers. + +TITLE: The Internet Message, Closing the book with Electronic Mail +AUTHOR: Rose, Marshall T. +PUBLISHER: Prentice Hall +DATE: 1993 +PAGES: 370 +ISBN: 0-13-092941-7 +APPROX_COST: <$$.cc> + +TITLE: Internetworking with TCP/IP +AUTHOR: Comer, Douglas +SUBJECT: Networking +PUBLISHER: Prentice-Hall +DATE: 1988 +PAGES: 382 +ISBN: 0-13-470154-2 +APPROX_COST: 47.00 +SUGGESTED_BY: Mitch Wright <mitch@hq.af.mil> +COMMENTS + -- From back of book + This comprehensive book begins with a discussion of the TCP/IP + technology and the Internet in general terms, summarizing the services + provided and the history of their development. + + The remainder of the book looks at the architecture of the Internet, + the TCP/IP technology, and the applications that use it in more + detail. It discusses the fundamentals of protocols like TCP/IP as + well as showing how they fit into the internet. In additon to + providing details, the book highlights the general principles + underlying network protocols, and explains why the TCP/IP protocols + adapt easily to so many underlying network technologies. Readers will + find a brief summary of the network hardware used throughout the + Internet that focuses on the features of each technology that are of + primary importance to an Internet architect. + +TITLE: Internetworking with TCP/IP Volume 1, 2nd Edition +AUTHOR: Comer, Douglas E. +SUBJECT: Networking: Principles, Protocols, and Architecture +PUBLISHER: Prentice Hall +DATE: 1991 +PAGES: 547 +ISBN: 0-13-468505-9 +APPROX_COST: 52.00 +SUGGESTED_BY: Mitch Wright <mitch@cirrus.com> +COMMENTS: + If you thought the first book was good, wait until you get ahold + of this second set. Now it's two volumes.... + +TITLE: Internetworking with TCP/IP Volume 2, 2nd Edition +AUTHOR: Comer, Douglas E. +AUTHOR: Stevens, David L. +SUBJECT: Networking: Design, Implementation, and Internals +PUBLISHER: Prentice Hall +DATE: 1991 +PAGES: 532 +ISBN: 0-13-472242-6 +APPROX_COST: 49.00 +SUGGESTED_BY: Mitch Wright <mitch@cirrus.com> + +TITLE: Internetworking with TCP/IP Volume 3 +AUTHOR: Comer, Douglas E. +AUTHOR: Stevens, David L. +SUBJECT: Networking: Design, Implementation, and Internals +PUBLISHER: Prentice Hall +DATE: 1992 +PAGES: 417 +ISBN: <isbn> +APPROX_COST: $50.00 +SUGGESTED_BY: Mitch Wright <mitch@cirrus.com> +COMMENTS + I got a glimse last month of this book... Needless to say I have + mine on order from my book club. With luck it will be here soon. + Looks like Comer and Stevens have another fine text on the shelf. + +TITLE: Introducing The UNIX System +AUTHOR: McGilton, Henry +AUTHOR: Morgan, Rachel +SUBJECT: Introduction to UNIX +PUBLISHER: McGraw-Hill Book Company +DATE: 1983 +PAGES: 556 +ISBN: 0-07-045001-3 +APPROX_COST: 27.95 +SUGGESTED_BY: "Michael J. Chinni, SMCAR-CCS-E" <mchinni@PICA.ARMY.MIL> +COMMENTS + Introductory for the most part, but far more extensive than Gauthier's + book. There are two chapters on editors and two on text formatting + that are the best I have seen in this type book. There is even a + chapter on system management. + + ... a later edition of this book was targeted specifically to + System V. -- Henry + +TITLE: Introducing UNIX System V +AUTHOR: Morgan, Rachel +AUTHOR: McGilton, Henry +SUBJECT: Introduction +PUBLISHER: McGraw-Hill +DATE: 1987 +PAGES: 612 +ISBN: 0-07-043152-3 +APPROX_COST: 24.95 +COST: 19.95 PBK +COMMENTS + It gives the user a good working knowledge of a number of commands + and packages. I emphasize that it is a user book, by no means a + technical manual. I assume by the difficulty in getting it in these + parts that it is pretty popular. + +TITLE: An Introduction to Berkeley Unix +AUTHOR: Wang, Paul +SUBJECT: Introduction +PUBLISHER: Wadsworth Publishing Company +DATE: 1988 +PAGES: 512 +ISBN: 0-534-08862-7 +APPROX_COST: 36.75 +KEYWORDS: BSD +COMMENTS + If you need a BSD oriented book, then I don't think you would find a + more thorough introductory book. + +TITLE: The Kornshell, Command and Programming Language +AUTHOR: Korn, David G. +AUTHOR: Bolsky, Morris I. +SUBJECT: Korn shell programming +PUBLISHER: Prentice-Hall +DATE: 1989 +PAGES: 356 +ISBN: 0-13-516972-0 +APPROX_COST: 30.00 +KEYWORDS: ksh, SYSV +SUGGESTED_BY: Mitch Wright <mitch@hq.af.mil> +COMMENTS + The book to have if you are beginning to learn the ksh. + +TITLE: LATEX: A Document Preparation System +AUTHOR: Lamport, Leslie +PUBLISHER: Addisson-Wesley +DATE: 1985 +PAGES: <pages> +ISBN: 0-201-15790-X +APPROX_COST: <$$.cc> +SUGGESTED_BY: "Diomidis Spinellis" <dds@doc.ic.ac.uk> +COMMENTS + Have it by your side when using LaTeX + +TITLE: Learning GNU Emacs +AUTHOR: Cameron, Deb +AUTHOR: Rosenblatt, Bill +SUBJECT: Editing +PUBLISHER: O'Reilly and Associates +DATE: 1992 +PAGES: 442 +ISBN: 0-937175-84-6 +APPROX_COST: 27.95 +KEYWORDS: Emacs, Editor, GNU +COMMENTS: + A book aimed at new Emacs users, whether or not they are + programmers. + +TITLE: Learning the Korn Shell +AUTHOR: Rosenblatt, Bill +SUBJECT: Shell +PUBLISHER: O'Reilly & Associates +DATE: 1993 +PAGES: 338 +ISBN: 1-56592-054-6 +APPROX_COST: $27.95 +KEYWORDS: shell, korn, programming +COMMENTS: + TABLE OF CONTENTS + 1 - Korn Shell Basics 7 - Input/Output and Command-line + 2 - Command-line Editing Processing + 3 - Customizing Your Environment 8 - Process Handling + 4 - Basic Shell Programming 9 - Debugging Shell Programs + 5 - Flow Control 10 - Korn Shell Administration + 6 - Command-line Options & + Typed Variables + +TITLE: Learning the UNIX Operating System +AUTHOR: Todino, Grace +SUBJECT: Introduction +PUBLISHER: O'Reilly & Associates, Inc. +DATE: 1987 +PAGES: 76 +ISBN: 0-937175-16-1 +APPROX_COST: 9.00 +KEYWORDS: Nutshell Handbook + +TITLE: Learning the vi Editor, 5th Edition +AUTHOR: Lamb, Linda +SUBJECT: Introduction +PUBLISHER: O'Reilly & Associates, Inc. +DATE: 1991 +PAGES: 192 +ISBN: 0-937175-67-6 +APPROX_COST: 21.95 +KEYWORDS: Nutshell Handbook + +TITLE: Learning to Program in C +AUTHOR: Plum, Thomas +SUBJECT: C Programming +PUBLISHER: Prentice Hall +DATE: 1983 +PAGES: 300 +ISBN: 0-13-527847-3 (pbk) +APPROX_COST: 20.00 +SUGGESTED_BY: Chet Creider <creider@taptet.sscl.uwo.ca> +COMMENTS + An old classic. + +TITLE: Learning Perl +AUTHOR: Schwartz, Randal L. +SUBJECT: Programming +PUBLISHER: O'Reilly & Associates +DATE: 1993 +PAGES: 246 +ISBN: 1-56592-04202 +APPROX_COST: $24.95 +KEYWORDS: Perl, programming. llama +SUGGESTED_BY: Mitch Wright <mitch@oz.com> +COMMENTS: + Yowza! Well, here it is folks, "the" book to teach you perl. No + more excuses no to learn one of the most useful and effective + programming languages of our time. This book provides a quick + ramp up for those with little time to spend, but need the power + perl provides. + +TITLE: Life With UNIX +AUTHOR: Libes, Don +AUTHOR: Ressler, Sandy +SUBJECT: Introduction and Overview of UNIX +PUBLISHER: Prentice-Hall +DATE: 1989 +PAGES: 350 +ISBN: 0-13-536657-7 +APPROX_COST: 30.95 +KEYWORDS: Introduction, Overview +COMMENTS + - A comprehensive overview of UNIX. Major sections are: + + UNIX in Time - Usual trash plus history of user groups, + universities, with a comprehensive "who's who" in + UNIX history. Present & Future deals with where + UNIX is now and where its going - companies, + standards and dialects are treated at length. + + UNIX Information - How people really learn about UNIX. + Discussion of books, magazines, conferences, and, of + course, source code. + + Inside UNIX - In-depth descriptions of UNIX from three + different perspectives - user, programmer and + adminstrator. + + Outside UNIX - Third-party stuff. Discussions of how UNIX + has prospered/withered in face of real-world problems. + Underground - archives, USENET, public access UNIX, + GNU, MINIX, public-domain and/or free software, etc. + + This book is quite unusual, not only because of its scope, but + because it prints things that have never appeared in print (for one + reason or another) - things that most people don't realize or find + until years after they have used UNIX. It is essentially a + "reading between the lines" of all the other UNIX manuals, books + and magazines. Lastly, "Life With UNIX" is chock full of amusing + UNIX stories and anecdotes, all designed to provide you with key + insights into why UNIX is the way it is. "Life with UNIX" is a + must book for UNIX beginners to UNIX gurus. + + { Best! Best! Best! Hooray -- loved it!!! S.B.Bassett } + +TITLE: lex & yacc, 2nd Edition +AUTHOR: Mason, Tony +AUTHOR: Brown, Doug +AUTHOR: Levine, John +SUBJECT: Unix lex and yacc utilites +PUBLISHER: O'Reilly and Associates +DATE: October 1992 +PAGES: 400 +ISBN: 1-56592-000-7 +APPROX_COST: 29.95 +KEYWORDS: lex, yacc +COMMENTS: + Shows programmers how to use two UNIX utilities, lex and yacc, + to solve problems in program development. Includes explanations + of the concepts and tutorial examples, as well as detailed technical + information for advanced users. + + LEX & YACC, 2nd edition, continues to be the only book exclusively + devoted to these two important UNIX programming tools. Every chapter + from the first edition has been wholly revised, with new, expanded + examples replacing old ones. + + Major changes (From 1st Edition) include: + + * Lex and yacc each have a chapter devoted to understanding + basic usage and simple, stand-alone applications; + + * A new chapter with full SQL grammar; + + * Greatly expanded reference chapters; + + * Coverage of the new POSIX 1003.2 standard versions of lex + and yacc; + + * Full coverage of all major MS-DOS and UNIX versions of lex + and yacc, including AT&T lex and yacc, Berkeley yacc, + Berkeley/Gnu flex, Gnu bison, MKS Lex and Yacc, and Abraxas + PCYACC. + +TITLE: MH & xmh: E-mail for Users & Programmers, 2nd Edition +AUTHOR: Peek, Jerry +SUBJECT: Electronic mail +PUBLISHER: O'Reilly and Associates +DATE: September 1992 +PAGES: 728 +ISBN: 1-56592-027-9 +APPROX_COST: 29.95 +KEYWORDS: E-mail, MH + + Customizing your e-mail environment to save time and make communicating + more enjoyable. MH & xmh: E-Mail for Users & Programmers explains how to + use, customize, and program with the MH electronic mail commands, available + on virtually any UNIX system. The handbook also covers xmh, an X Window + System client that runs MH programs. + + The new 2nd edition has been updated for X Release 5 and MH 6.7.2. + We've added a chapter on "mhook", new sections explaining under-appreciated + small commands and features, and more examples showing how to use MH to + handle common situations. + + NOTE: Over 100 pages added since the 1st edition. + +TITLE: Managing NFS and NIS +AUTHOR: Stern, Hal +SUBJECT: Networking +PUBLISHER: O'Reilly & Associates, Inc. +DATE: 1991 +PAGES: 436 +ISBN: 0-937175-75-7 +APPROX_COST: 27.95 +KEYWORDS: YP, NIS, NFS, PC/NFS +SUGGESTED_BY: stern@sunne.East.Sun.COM (Hal Stern - Consultant) +COMMENTS: + The book includes the usual discussions of setting up and + administering NFS and NIS, but it focuses much more on the + system design, on-going maintenance, growth management and + performance tuning issues that seem to create the most problems. + The chapters include: + + - NIS applications: how to build your own maps, and write + applications that use NIS map files + + - NFS design and operation: what biod and nfsd really do. + how file attribute caching works. + + - Using NFS and NIS to centralize mail delivery + + - Network Security, including a discussion of Secure RPC/NFS + + - Diagnostic Tools, focusing on debugging and problem isolation + + - Performance Analysis and Tuning + + - The Automounter + + - PC/NFS + + There's also an appendix describing various NFS benchmarking + techniques and tools. + +TITLE: Managing Projects with Make, 2nd Edition +AUTHOR: Oram, Andrew +AUTHOR: Talbot, Steve +SUBJECT: Introduction to make(1) +PUBLISHER: O'Reilly & Associates, Inc. +DATE: 1991 +PAGES: 135 +ISBN: 0-937175-90-0 +APPROX_COST: 17.95 +KEYWORDS: Nutshell Handbook + +TITLE: Managing UUCP and USENET, 10th Edition +AUTHOR: O'Reilly, Tim +AUTHOR: Todino, Grace +SUBJECT: Introduction to UUCP and Usenet +PUBLISHER: O'Reilly & Associates, Inc. +DATE: 1991 +PAGES: 368 +ISBN: 0-937175-93-5 +APPROX_COST: 27.95 +KEYWORDS: Nutshell Handbook +SUGGESTED_BY: Mitch Wright <mitch@hq.af.mil> +COMMENTS + For all its widespread use, UUCP is one of the most difficult UNIX + utilities to master. This book is for system administrators who + want to install and manage UUCP and Usenet software. "Don't even + TRY to install UUCP without it!" -- Usenet message 456@nitrex.UUCP + +TITLE: Modern Operating Systems +AUTHOR: Tanenbaum, Andrew S. +SUBJECT: Operating systems +PUBLISHER: Prentice Hall +DATE: 1992 +PAGES: <715+> +ISBN: 0-13-588187-0 +APPROX_COST: <??.??> +KEYWORDS: OS, UNIX, Plan 9, MACH +COMMENTS + From the preface... + [...] + During the past 15 years, I have personally helped design + and implement three different operating systems: + TSS-11 (PDP-11), MINIX (IBM PC, Atari, Amiga, Macintosh, + and SPARC), and Amoeba (80386, Sun-3, SPARC, and VAX). I have + drawn on this long experience to emphasize those topics that + actually matter in real systems. All the subjects that are + expected in an undergraduate text on operating systems are + included here, including processes, interprocess communication, + semaphores, monitors, message passing, classical IPC problems, + scheduling, swapping, virtual memory, paging algorithms, + segmentation, file systems, security, [...] + -- Andrew S. Tanenbaum + +TITLE: Notes on the Draft C Standard +AUTHOR: Plum, Thomas +SUBJECT: C Programming +PUBLISHER: Plum Hall +DATE: 1987 +PAGES: 92 +ISBN: 0-911537-06-6 +APPROX_COST: 10.00 +COMMENTS + Tom Plum is the Vice Chair of the ANSI X3J11 committee, so who better + to write this book than he? However, as with any of the other C books + that treat the ANSI C Standard, it does not cover the Standard in it's + final form due to the fact that it has yet to be adopted. However, + the price is about $10, so it makes a good pickup to keep informed + about the standard and how it differs from K&R C. + +TITLE: Numerical Recipes in C, The Art of Scientific Computing +AUTHOR: Press, William H. +AUTHOR: Flannery, Brian +AUTHOR: Teukolsky, Saul +AUTHOR: Vetterling, William +SUBJECT: C Programming +PUBLISHER: Cambridge University Press +DATE: 1988 +PAGES: 735 +ISBN: 0-521-35465-X +APPROX_COST: 44.50 +SUGGESTED_BY: Mitch Wright <mitch@hq.af.mil> +COMMENTS + ". . . it is the one book to buy if you are going to have to solve + anything numerically on a computer." - Dr. Dobb's Journal + +TITLE: Obfuscated C and Other Mysteries +AUTHOR: Libes, Don +SUBJECT: C Programming +PUBLISHER: John Wiley & Sons +DATE: 1993 +PAGES: 425, including disk with complete source code +ISBN: 0-471-57805-3 +COMMENTS + Finally, an educational yet entertaining book for C + programmers - or anyone else who wants to make fun of the + language. + + "Obfuscated C ..." contains 40 essays that explain various + mysteries of the language (or perhaps just the author's + confusion over it) in an enjoyably light-hearted and humorous + style. Included are explanations of all of the winners of the + Obfuscated C Code Contest from 1985 to 1991. You've seen them + before, but a superficial glance doesn't do them justice. + Each of these seemingly short programs are wonderfully + constructed knots of clever syntax and logic. You'll cry for + hours and laugh for days. + + Keep this book away from children! You've been warned! + +TITLE: Object-oriented Software Construction +AUTHOR: Meyer, Berstrand +PUBLISHER: Prentice Hall +DATE: 1988 +PAGES: <pages> +ISBN: 0-13-629031-0 +APPROX_COST: <$$.cc> +SUGGESTED_BY: "Diomidis Spinellis" <dds@doc.ic.ac.uk> +COMMENTS + A strong, personal view on object oriented programming. A good + introduction to the Eiffel language. + +TITLE: The Open Book +AUTHOR: Rose, Marshall T. +SUBJECT: OSI +PUBLISHER: Prentice-Hall +DATE: 1990 +PAGES: 651 +ISBN: 0-13-643016-3 +APPROX_COST: +KEYWORDS: Networking +SUGGESTED_BY: Mitch Wright <mitch@hq.af.mil> +COMMENTS: + -- From back cover -- + This book is an important contribution to the networking literature + for two reasons. First, it is one of the clearest expositions of the + OSI architecture and protocols, and it deals with concrete issues, + including implementation matters. Second, it seeks to explicate ways + in which the TCP/IP Internet community may accommodate the phased + introduction of OSI protocols. This latter contribution is of prime + importance if this large and rapidly growing community is to benefit + from the heavy vendor community investment in OSI software and + services. + -- Vint Cerf, Chariman, Internet Activities Board + +TITLE: Operating Systems, Design and Implementation +AUTHOR: Tanenbaum, Andrew S. +SUBJECT: OS Design +PUBLISHER: Prentice-Hall +DATE: 1987 +PAGES: 719 +ISBN: 0-13-637406-9 +APPROX_COST: 40.00 +KEYWORDS: MINIX, UNIX +SUGGESTED_BY: Mitch Wright <mitch@oz.com> +COMMENTS + -- From back cover -- + o Covers the fundamental principles in detail including processes, + interporcess communication, semaphores, monitors, message passing, + remote procedure call, scheduling algorithms input/output, + deadlocks, device drivers, memory management, paging algorithms, + file system design, network file servers, atomic transactions, + security, and protection mechanisms. + o discusses one system -- MINIX, a UNIXX-compatible operating + system -- in detail to illustrate the principles. + o provides a complete source code listing of MINIX for study. + +TITLE: Operating System Design, The XINU approach +AUTHOR: Comer, Douglas +SUBJECT: OS Design +Publisher: Prentice-Hall +DATE: 1984 +PAGES: 486 +ISBN: 0-13-637539-1 +APPROX_COST: 39.95 +SUGGESTED_BY: Mitch Wright <mitch@oz.com> +COMMENTS: + -- From back cover -- + In this book, Douglas Comer, dispels the magic from operating system + design and consolidates the body of material into a systematic + discipline... + + The author guides you through the construction of a conventional + process-based system, using practical straightforward primitives... + +TITLE: POSIX Programmer's Guide +AUTHOR: Lewine, Donald +SUBJECT: POSIX +PUBLISHER: O'Reilly and Associates +DATE: 1991 +PAGES: 640 +ISBN: 0-937175-73-0 +APPROX_COST: 34.95 +KEYWORDS: Posix, standards + +TITLE: Peter Norton's Guide to Unix +AUTHOR: Norton, Peter +AUTHOR: Hahn, Harley +PUBLISHER: Bantam Books +DATE: 1991 +PAGES: 560 +ISBN: 0-553-35260-1 +APPROX_COST: 26.95 +SUGGESTED_BY: Lawrence R. Gibes <lgibes@teal.csn.org> + +TITLE: Portable C Software +AUTHOR: Horton, Mark +SUBJECT: C programming +PUBLISHER: Prentice Hall +DATE: 1990 +PAGES: 400 +ISBN: 0-13-868050-7 +APPROX_COST: 32.95 +COMMENTS: + ** From the back jacket: + + Portable C Software is designed for professional programmers and + students who want to write portable C code between System V + implementations, POSIX, MS DOS, and other operating systems. + + Assuming a working knowledge of C, this book addresses and rates + each feature of the C software environment. Shell commands, system + calls, external variables, and macros are discussed and examined + in detail. + + The author provides an advanced introduction to C, describes how + best to write portable software, examines what not to do, discusses + common mistakes, and includes an invaluable portability reference + manual. In this extensive manual, the author rates the portability + of the following + + o subroutines available in C libraries + o operating system calls + o header include files + o predefined variables in the C library + o UNIX(R) system shell commands + + Portable C Software offers concise, current coverage of C, and + will be an important reference for anyone who writes C programs. + + Of the nearly 400 pages, about 250 are reference material. Some of it + is fairly detailed. If you find any errors, or have any suggestions + for the next edition, please drop me a note at + + Mark.Horton@ATT.COM + + Thanks to everyone who made helpful suggestions or otherwise + contributed to the book. -- Mark + +TITLE: Portable C and UNIX System Programming +AUTHOR: Lapin, J.E. +SUBJECT: C programming +PUBLISHER: Prentice-Hall +DATE: 1987 +PAGES: 249 +ISBN: 0-13-686494-5 +KEYWORDS: Portable C +COMMENTS + A useful book, mostly because there are no others written on this + topic, yet... + +TITLE: Postscript Language Program Design +AUTHOR: Adobe Systems Incorporated +PUBLISHER: Addison-Wesley +DATE: 1988 +PAGES: <pages> +ISBN: 0-201-14396-8 +APPROX_COST: <$$.cc> +SUGGESTED_BY: "Diomidis Spinellis" <dds@doc.ic.ac.uk> +COMMENTS + A must for writing serious PostScript programs. + +TITLE: Postscript Language Reference Manual +AUTHOR: Adobe Systems Incorporated +PUBLISHER: Addison-Wesley +DATE: <date> +PAGES: <pages> +ISBN: 0-201-10174-2 +APPROX_COST: <$$.cc> +SUGGESTED_BY: "Diomidis Spinellis" <dds@doc.ic.ac.uk> +COMMENTS + The standard PostScript reference. + +TITLE: Practical C Programming +AUTHOR: Oualline, Steve +SUBJECT: C programming +PUBLISHER: O'Reilly and Associates +DATE: 1992 +PAGES: 420 +ISBN: 0-937175-65-X +APPROX_COST: 24.95 +KEYWORDS: C, programming + +TITLE: A Practical guide to UNIX System V +AUTHOR: Sobell, Mark G. +SUBJECT: UNIX System V +PUBLISHER: Benjamin/Cummings Publishing Co. +DATE: 1985 +PAGES: 577 +ISBN: 0-80-538915-6 +APPROX_COST: 32.25 + +TITLE: A Practical Guide to the Unix System (2nd ed.) +AUTHOR: Sobell, Mark G. +SUBJECT: UNIX Guide +PUBLISHER: Benjamin/Cummings Publishing Co. +DATE: 1989 +PAGES: 632 +ISBN: 0-80-530243-3 +APPROX_COST: 27.95 + +TITLE: Practical UNIX Security +AUTHOR: Garfinkel, Simson +AUTHOR: Spafford, Gene +SUBJECT: Unix security +PUBLISHER: O'Reilly and Associates +DATE: 1991 +PAGES: 512 +ISBN: 0-937175-72-2 +APPROX_COST: 29.95 +KEYWORDS: security +SUGGESTED_BY: "Cliff Stoll" <cliff@cfa.harvard.edu> +COMMENTS + Here's how to secure your Unix system -- where the security + holes are, what to watch out for, how outsiders break in, + how to secure your system in a networked environment. + The best technical book on the subject that I've seen, + written for systems people who need to know. It'll save + you its purchase price in asprin. + +TITLE: Power Programming with RPC +AUTHOR: Bloomer, John +SUBJECT: RPC Programming +PUBLISHER: O'Reilly and Associates +DATE: 1991 +PAGES: 494 +ISBN: 0-937175-77-3 +APPROX_COST: 29.95 +KEYWORDS: RPC, Nutshell +COMMENTS + Contents include: + -- The foundations of remote procedure calling; what it is, + how it works and what vendors support it. + -- What RPC offers to application and product developers. + -- How RPC fits into a distributed computing environment + -- ONC and DCE, a comparison of their similarities and differences. + -- How to develop, debug and deploy networked applications. + -- Understanding the interprocess control (IPC) mechanisms on + which RPC is based. + -- Using remote procedure calling in parallel/distributed + processing and scheduling. + -- Using remote procedure calling with windowing systems. + -- Examples of distributed applications using both single and + multiple concurrent servers. + +TITLE: Programming perl +AUTHOR: Wall, Larry +AUTHOR: Schwartz, Randal L. +SUBJECT: Programming in perl +PUBLISHER: O'Reilly & Associates, Inc. +DATE: 1991 +PAGES: 465 +ISBN: 0-937175-64-1 +APPROX_COST: 29.95 +KEYWORDS: perl, nutshell +SUGGESTED_BY: Mitch Wright <mitch@oz.com> +COMMENTS: + OUTSTANDING!!!!!!! I've had mine since USENIX and it's been with + me since then. I just don't leave home without it. This book is + for you if you are even slightly interested in perl as a language, + and it's easy reading and excellent examples will make you, as + Randal would say ``Just Another Perl Hacker''. It is even worth + reading if you are not *yet* interested in the language. + Programming perl is very light reading and in the words of Larry: + "...mildly amusing in some spots (and wildly amusing in others)." + + From back cover: Perl is a language for easily manipulating text + files and processes. Perl provides a more concise and readable way to + do many jobs that were formally accomplished (with difficulty) by + programming in the C language or one of the shells. Even though Perl + is not yet a standard part of UNIX, it is likely to be available at + any UNIX site. And if it isn't, users can get it and install it + easily and FREE of charge. + +TITLE: Programming with Curses +AUTHOR: Strang, John +SUBJECT: Introduction +PUBLISHER: O'Reilly & Associates, Inc. +DATE: 1986 +PAGES: 76 +ISBN: 0-937175-02-1 +APPROX_COST: 12.95 +KEYWORDS: Nutshell Handbook +COMMENTS + curses is a UNIX library of functions for controlling a terminal's + display screen from a C program. This handbook helps you make use of + the curses library. + +TITLE: RS-232 Card +AUTHOR: SSC Staff +SUBJECT: Pocket-sized reference card RS-232 serial communications +PUBLISHER: SSC (Specialized Systems Consultants, Inc.) +DATE: 1990 +PAGES: 8 +ISBN: 0-916151-42-7 +APPROX_COST: $3.00 +KEYWORDS: RS-232, serial communications, reference card +SUGGESTED_BY: Phil Hughes fyl@ssc.wa.com +COMMENTS + Concise explanation of the RS-232 standard for serial communications. + Includes signal descriptions, pinouts for both DB-25 and DB-9 + connectors, null modem wiring and an ASCII code chart. + +TITLE: Recommended C Stype and Coding Standards +AUTHOR: Keppel, David +AUTHOR: ...others... +SUBJECT: Revision of Indian Hill C Style paper +PUBLISHER: SSC (Specialized Systems Consultants, Inc.) +DATE: June, 1991 +PAGES: 40 +ISBN: 0-916151-46-8 +APPROX_COST: $5.00 +KEYWORDS: C language, programming style +SUGGESTED_BY: Phil Hughes fyl@ssc.wa.com +COMMENTS + Describes a recommended coding standard for C language programs. + +TITLE: sed & awk +AUTHOR: Dougherty, Dale +SUBJECT: Sed and awk programming +PUBLISHER: O'Reilly and Associates +DATE: 1990 +PAGES: 414 +ISBN: 0-937175-59-5 +APPROX_COST: 27.95 +KEYWORDS: sed, awk + +TITLE: sendmail +AUTHOR: Costales, Bryan +AUTHOR: Allman, Eric +AUTHOR: Rickert, Neil +SUBJECT: sendmail admin. +PUBLISHER: O'Reilly & Associates +DATE: 1993 +PAGES: 792 +ISBN: 1-56592-056-2 +APPROX_COST: $32.95 +KEYWORDS: sendmail, e-mail +SUGGESTED_BY: Mitch Wright <mitch@oz.com> +COMMENTS: + It's been a long time waiting, but Bryan Costales has created an + excellent and authoratative work on one of the most "magical" + programs in UNIX. The black art of sendmail has been uncovered + and it's mysteries (most of them) have been solved. With help + from Eric Allman (creator of sendmail) and Neil Rickert this book + covers not only the traditional Version 5.x of sendmail, but things + like the new V8 and IDA sendmail. The book is well broken up and + provides a tutorial, followed by an administration section, then a + reference section, and finally (670 pages later) the appendices. + +TITLE: The SPARC System Developer's Guide +AUTHOR: Leventhal, L. +AUTHOR: Rohner, J. +SUBJECT: SPARC Assemble Language +PUBLISHER: Springer-Verlag +DATE: 1989 +PAGES: <pages> +ISBN: 0-387-97251-X +APPROX_COST: 39.95 +KEYWORDS: SPARC + +TITLE: The Standard C Library +AUTHOR: Plauger, P.J. +SUBJECT: C Programming +PUBLISHER: Prentice Hall +DATE: 1990 +PAGES: 498 +ISBN: 0-13-131509-9 +APPROX_COST: 28.00 +KEYWORDS: C, libc, programming + +TITLE: A Student's Guide to UNIX +AUTHOR: Hahn, Harley +SUBJECT: UNIX +PUBLISHER: McGraw-Hill +DATE: 1993 +PAGES: 633 +ISBN: 0-07-025511-3 +APPROX_COST: <price> +COMMENTS: + Here is a book that will help you ramp up your UNIX expertise + quickly. The book is organized well and takes an honest view + of what is out there. Harley even tells you about MUD (p.430), + but kindly warns you about it's effects on the graduation rate... + I suppose the time I saved reading this book will allow me the + time for a few minutes of studying... + + [This is the first book I have read that actually spells out + the infamous RTFM -- in fine fashion I might add. Page 430 + ~mitch] + +TITLE: Software Copyright Handbook +AUTHOR: Joel B. Gilman +SUBJECT: Step-by-step guide to obtaining a software copyright +PUBLISHER: SSC (Specialized Systems Consultants, Inc.) +DATE: June, 1991 (revised) +PAGES: 29 +ISBN: 0-916151-45-X +APPROX_COST: $9.95 +KEYWORDS: software copyrights +SUGGESTED_BY: Phil Hughes fyl@ssc.wa.com +COMMENTS + "Understandability: Almost Crystal Clear" and "Summary: A + quick rundown of the simple requirements for gaining + copyright protection." -- Walter Zintz, UNIX World, September, 1991 + +TITLE: Software Engineering in C. +AUTHOR: Darnell, Peter A. +AUTHOR: Margolis, Philip E. +SUBJECT: C programming +PUBLISHER: Springer-Verlag +DATE: 1988 +PAGES: 612 +ISBN: 0-387-96574-2 +APPROX_COST: 29.95 +SUGGESTED_BY: srvarma@rodan.acs.syr.edu +COMMENTS + One of the finest books I have seen for beginners. Highly recommended + even for intermediate-level C programmers. + +TITLE: Software Tools +AUTHOR: Kernighan, Brian W. +AUTHOR: Plauger, P. J. +SUBJECT: How to write programs that make good tools. +PUBLISHER: Addison-Wesley +DATE: 1976 +PAGES: 338 +ISBN: 0-201-03669-X +APPROX_COST: 20.00 +KEYWORDS: programming, top-down design, software engineering. +COMMENTS + The language used is RATFOR but it looks enough like C + to be used by anyone who knows or is learning C. + The book purports to contain generic examples that might + be on any system; the reader will recognise many similarities + to UNIX. + Several UNIX-like commands and features are discussed in + detail. Many UNIX design considerations and philosophies + are explained. + +TITLE: System Performance Tuning +AUTHOR: Loukides, Mike +SUBJECT: System Performance +PUBLISHER: O'Reilly & Associates, Inc. +DATE: 1991 +PAGES: 336 +ISBN: 0-937175-60-9 +APPROX_COST: 24.95 +KEYWORDS: performance, nutshell +COMMENTS: + *** From: ORA Fall/Winter 1990 Catalog + System Performance Tuning answers one of the most fundamental + questions you can ask abou your computer: "How can I get it to + do more work without buying more hardware?" Anyone who has + ever used a computer has periodically wished that the system + was faster, particularly at times when it was under heavy load. + +TITLE: Software Portability with imake +AUTHOR: DuBois, Paul +SUBJECT: programming +PUBLISHER: O'Reilly & Associates +DATE: 1993 +PAGES: 390 +ISBN: 1-56592-055-4 +APPROX_COST: $27.95 +KEYWORDS: X, programming, make +COMMENTS: + From a marketing blurb: imake is a utility that works with make to + enable code to be compilied and installed on different UNIX machines. + This new nutshell handbook -- the only book available on imake -- is + ideal for X and UNIX programmers who want their software to be + portable. It includes a general explanation of imake, how to write + and debug an Imakefile, and how to write configuration files. + +TITLE: The TCP/IP Companion: A Guide for the Common User +AUTHOR: Arick, Martin R. +SUBJECT: Using TCP/IP +PUBLISHER: QED Publishing Group +DATE: August 1993 +PAGES: 263 +ISBN: 0-89435-466-3 +APPROX_COST: $29.95 +KEYWORDS: TCP/IP INTERNET NETWORKING +SUGGESTED BY: Rich O'Hanley, QED, 76620.2720@compuserve.com +COMMENTS: + Step-by-step instructions on how to use TCP/IP protocols: + rlogin, telnet, rcp, rsh, tftp and smtp, ftp, mail, mount, + and network services. + +TITLE: TCP/IP Network Administration +AUTHOR: Hunt, Craig +SUBJECT: TCP/IP Networking +PUBLISHER: O'Reilly and Associates +DATE: July 1992 +PAGES: 502 +ISBN: 0-937175-X +APPROX_COST: $29.95 +KEYWORDS: TCP, IP, Networking, Admin +COMMENTS: + A complete guide to setting up and running a TCP/IP network for + practicing system administrators. Covers how to set up your network, + how to configure important network applications including sendmail, + and discusses troubleshooting and security. + Covers BSD and System V TCP/IP implementations. + +TITLE: TCP/IP and Related Protocols +AUTHOR: Black, Uyless +SUBJECT: TCP/IP Networking +PUBLISHER: McGraw Hill +DATE: 1992 +PAGES: <pages> +ISBN: 0-07-005553-X +SUGGESTED_BY: James Petts <pettsj@visigoth.demon.co.uk> +COMMENTS + Chapter 1. TCP/IP and the Internet + Chapter 2. Introduction to Betworks, Bridges, Gateways, + and Routers + Chapter 3. Naming, Addressing, and Routing in an Internet + Chapter 4. The Domain Name System (DNS) + Chapter 5. The Internet Protocol (IP) + Chapter 6. Internet Control Message Protocol (ICMP) + Chapter 7. Transmission Control Protocol (TCP) and User + Datagram Protocol (UDP) + Chapter 8. Route Discover Protocols + Chapter 9. The Major Application Layer Protocols + Chapter 10. Other Protocols + Chapter 11. Internet Network Management Systems + Chapter 12. Operating TCP/IP with Other Protocols + (and Other Protocols without TCP/IP) + Chapter 13. TCP/IP and Operating Systems + Chapter 14. Management Considerations + + A book written in an "advanced tutorial style", this gives a + thorough and clear introduction to TCP/IP from a technical point + of view, but also gives some emphasis to the place of TCP/IP in + internetworking from an integration and management point of view. + +TITLE: The TeXbook +AUTHOR: Knuth, Donald E. +PUBLISHER: Addisson-Wesley +DATE: 1989 +PAGES: <pages> +ISBN: 0-201-13448-9 +APPROX_COST: <$$.cc> +SUGGESTED_BY: "Diomidis Spinellis" <dds@doc.ic.ac.uk> +COMMENTS + The standard book on TeX. + +TITLE: Termcap & Terminfo, 3rd Edition +AUTHOR: Strang, John +AUTHOR: Mui, Linda +AUTHOR: O'Reilly, Tim +SUBJECT: Introduction +PUBLISHER: O'Reilly & Associates, Inc. +DATE: 1990 +PAGES: 270 +ISBN: 0-937175-22-6 +APPROX_COST: 21.95 +KEYWORDS: Nutshell Handbook +SUPPLIERS + E-mail: ... uunet!ora!nuts + Phone#: 1-800-338-NUTS + +TITLE: Tricks of the UNIX Masters +AUTHOR: Sage, Russel G. +SUBJECT: Reference +PUBLISHER: Howard Sams & Co +DATE: 1987 +PAGES: 400 +ISBN: 0-672-22449-6. +APPROX_COST: 24.95 +COMMENTS + a "must add" to your list of UNIX books. For about $20, you'll get a + lot of nifty little tricks & tips you won't pick up unless you've got + a good UNIX guru to coach you. The style is relaxed & aimed at a bit + above the novice UNIX user (experienced programmer with sparse UNIX + exposure). + +TITLE: Typesetting Tables on the UNIX System +AUTHOR: McGilton, Henry +AUTHOR: McNabb, Mary +SUBJECT: Using the 'tbl' utility +PUBLISHER: Trilithon Press, 334 State St., Ste. 106 Los Altos CA 94022 +DATE: 1990 +PAGES: 280 +ISBN: 0-9626289-0-5 +APPROX_COST: 24.95 +KEYWORDS: Typesetting, tbl, troff +COMMENTS + -- From the back cover: + + Reviewers said: + "You're a pair of lunatics!" -- James Gosling, Sun Micro + "Good Grief!" -- Ken Greer, Elan Computer Group, Inc. + "Three Hundred Pages on TBL?!?" -- Prof. Powell, U. Minn + + I (S.B.Bassett) rather agree, but I wish there were more lunatics like + these two, who would do a thorough job of documenting the workings of + various cryptic, arcane, and downright quirky UNIX utilities for the + benefit of those of us without source . . . + + I actually enjoyed reading this -- Henry sent me a complimentary copy + in the hopes that I would review it here (thanks, Henry, I did), and I + figured out why I had so much trouble with 'tbl' on a former job -- I'd + have paid several times the price for a copy of this 2 years ago. Too + bad I'm not doing tech writing any more . . . ;^) + +TITLE: UNIX C Shell Desk Reference +AUTHOR: Arick, Martin K. +SUBJECT: UNIX C Shell +PUBLISHER: QED Information Sciences +DATE: 1991 +PAGES: 220 +ISBN: 0-89435-321-4 +APPROX_COST: $29.95 +KEYWORDS: C_Shell +SUGGESTED_BY: R O'Hanley, 76620.2720@compuserve.com + +TITLE: The UNIX C Shell Field Guide +AUTHOR: Anderson, Gail +AUTHOR: Anderson, Paul +SUBJECT: C-Shell Guide +PUBLISHER: Prentice-Hall +DATE: 1986 +PAGES: 374 +ISBN: 0-13-937468-X +APPROX_COST: 31.00 +KEYWORDS: C-shell, csh +SUGGESTED_BY: "Michael J. Chinni, SMCAR-CCS-E" <mchinni@PICA.ARMY.MIL> +COMMENTS + I have heard this called the C-Shell Bible. + +TITLE: UNIX Curses Explained +AUTHOR: Goodheart, Berny +SUBJECT: Complete Curses and Terminfo reference +PUBLISHER: Prentice-Hall +DATE: 1990 +PAGES: 304 +ISBN: 0-13-931957-3 +SUGGESTED_BY: goodheart_berny@tandem.com +KEYWORDS: Introduction, Overview, Curses +COMMENTS + This is a complete text and reference book on UNIX Curses. + It provides C programmers and UNIX users with the expertise to + create, install and debug, Curses written applications and + terminfo description files using the UNIX System V.3 Operating + System. + + Will enable any C programmer to create UNIX Curses or terminfo + based programs. + + The text is based on UNIX System V.3 and refers to earlier + releases where appropriate. + + In text examples on: using Curses; using Windows; color manipulation; + using an alternative character set; pads; and terminfo. + + The book includes a full alphabetical reference section (120pp) + documenting all curses functions from both past and present versions + of the UNIX operating system. + + An appendix with terminfo reference tables for both the terminfo + description designer and the C programmer. + +TITLE: The UNIX Industry: + Evolution, Concepts, Architecture, Applications, and Standards +AUTHOR: Dunphy, Edward P. +SUBJECT: UNIX market analysis +PUBLISHER: QED Information Sciences +DATE: 1991 +PAGES: 338 +ISBN: 0-89435-390-X +APPROX_COST: $34.95 +SUGGESTED_BY: R O'Hanley, 76620.2720@compuserve.com + +TITLE: UNIX Network Programming +AUTHOR: Stevens, W. Richard +SUBJECT: UNIX Networking +PUBLISHER: Prentice Hall +DATE: 1990 +PAGES: 772 +ISBN: 0-13-949876-1 +EDITION: 1990 +APPROX_COST: 40.00 +KEYWORDS: TCP/IP, XNS, SNA, NetBIOS, OSI, UUCP +SUGGESTED_BY: Richard Stevens ... { uunet | yale } ! hsi ! stevens +SUPPLIERS + (201) 767-5937 for fewer than 20 copies + (201) 592-2498 for corporate customers ordering 20 or more + (201) 767-5994 for Government orders +COMMENTS + -- From back cover + As networking software becomes increasingly importat in today's world, + a book that teaches programmers how to write and how better to use + this technology has finally arrived. + + ... is unique because it includes numerous case studies of real + network applications, as well as approximately 15,000 lines of + C source code, take directly from their source files, to help further + understanding of networking software. + + [ Source is available for anon. ftp at uunet.uu.net ~mitch ] + +TITLE: UNIX Networking +AUTHOR: Kochan, Stephen G. +AUTHOR: Wood, Patrick H. +SUBJECT: UNIX Networking +PUBLISHER: Hayden Books +DATE: 1989 +PAGES: 400 +ISBN: 0-672-48440-4 +APPROX_COST: 29.95 +KEYWORDS: Networking, TCP, NFS +SUGGESTED_BY: Frank W. Peters <peters@apple!CC.MsState.Edu> +COMMENTS + An excellent book covering UUCP, TCP/IP, NFS, RPC, Streams, OSI, RFS, + X11 and NeWS (Sun's postscript based graphical protocol). Each chapter + serves as an excellent programmers introduction to the topic + discussed." + +TITLE: UNIX Papers for UNIX Developers & Power Users +AUTHOR: The Waite Group Editors - edited by Mitchell Waite +SUBJECT: UNIX Reference +PUBLISHER: Howard W. Sams & Co +DATE: 1987 +PAGES: 518 +ISBN: 0-672-22578-6 +APPROX_COST: 26.95 +COMMENTS + This is a collection of papers. Some of the them are introductions + and others cover more arcane bits of knowledge. + +TITLE: UNIX Power Tools +AUTHOR: Peek, Jerry +AUTHOR: Loukides, Mike +AUTHOR: O'Reilly, Tim +AUTHOR: "other contributors" +SUBJECT: UNIX +PUBLISHER: O'Reilly & Associates +DATE: 1993 +PAGES: 1,162 +ISBN: 0-553-35402-7 +APPROX_COST: $59.95 (w/ CD) +KEYWORDS: CD, UNIX, "Arr, Arr, Arr" +SUGGESTED_BY: Mitch Wright <mitch@yahoo.cirrus.com> +COMMENTS: + Hey! It's "tool time". You need a book with "more power"? Well, + this is the one -- Arr, Arr, Arr. No need for Al to help out on + with using this tool. This book is made for *power*. It has 1100+ + pages firmly planted on a layflat binding (arr, arr, arr)... real + paper pages filled with high levels of toner for maximum power in + those learning curves (arr, arr, arr, arr). It even comes equipped + with a CD (AM/FM radio and player not included!). + +TITLE: UNIX time-sharing system : UNIX programmer's manual vol 1&2 +AUTHOR: BELL Laboratories +PUBLISHERS: Holt, Rinehart and Winston +SUBJECT: UNIX... +PUBLISHER: Bell Laboratories +DATE: 1983 +PAGES: +ISBN: 0-03-061742-1 (v1) +ISBN: 0-03-061742-X (v2) +APPROX_COST: + +TITLE: The UNIX Programming Environment +AUTHOR: Kernighan, Brian W. +AUTHOR: Pike, Rob +SUBJECT: Basic UNIX Programming +PUBLISHER: Prentice-Hall +YEAR: 1984 +PAGES: 357 +ISBN: 0-13-937699-2 HBK +ISBN: 0-13-937681-X PBK +APPROX_COST: 25.95 +SUGGESTED_BY: *Everyone* +COMMENTS + This book is what I call a classic. Just buy it. + A good programmer's introduction. + +TITLE: UNIX SVR4, The Complete Reference +AUTHOR: Coffin, Stephen +SUBJECT: UNIX Reference +PUBLISHER: Osborne-McGraw Hill +DATE: 1990 +PAGES: 882 +ISBN: 0-07-881653-X +APPROX_COST: 29.95 +SUGGESTED_BY: S.Coffin <scoffin@uswest.com> +COMMENTS + An update, revision, expansion, and overall improvement of the + best-selling UNIX, The Complete Reference (ISBN 0-07-881299-2). + Written especially for SVR4. New chapters on csh and ksh, troff, + NFS and networking, and X Window System, as well as wholesale + revision of many other chapters. Well-written, readable, complete; + but does not cover UNIX internals or software development. + +TITLE: UNIX System 5 (Bourne) Shell Tutorial +AUTHOR: SSC Staff +SUBJECT: Pocket-sized tutorial card on the System 5 shell +PUBLISHER: SSC (Specialized Systems Consultants, Inc.) +DATE: 1990 +PAGES: 48 +ISBN: 0-916151-39-5 +APPROX_COST: $6.00 +KEYWORDS: shell programming, pocket tutorial +SUGGESTED_BY: Phil Hughes fyl@ssc.wa.com +COMMENTS + Tutorial on the use of the shell. Covers the shell as a + command interpreter and as a programming language. Includes + a reference section and a summary of commonly used commands. + +TITLE: UNIX V.4 C Library Reference +AUTHOR: SSC Staff +SUBJECT: Pocket reference on C library functions of SVR4 +PUBLISHER: SSC (Specialized Systems Consultants, Inc.) +DATE: June, 1991 +PAGES: 80 +ISBN: 0-916151-47-6 +APPROX_COST: $8.00 +KEYWORDS: C library, ANSI C library, pocket reference +SUGGESTED_BY: Phil Hughes fyl@ssc.wa.com +COMMENTS + Documents the functions and system calls available to the + C programming using UNIX System V, Release 4. ANSI prototypes + are used to illustrate the calling conventions of the functions. + Functions that are part of the ANSI standard library are flagged. + Designed to complement the SSC ANSI C card. + +TITLE: UNIX System V.4 Command Summary +AUTHOR: SSC Staff +SUBJECT: Pocket-sized book listing SVR4 commands +PUBLISHER: SSC (Specialized Systems Consultants, Inc.) +DATE: December, 1990 +PAGES: 80 +ISBN: 0-916151-44-1 +APPROX_COST: $8.00 +KEYWORDS: UNIX SVR4, commands, pocket reference +SUGGESTED_BY: Phil Hughes fyl@ssc.wa.com +COMMENTS + Includes commands, options and explanations as well as special + sections on awk/nawk, sed, ftp, sdb and telnet. + +TITLE: UNIX System 5.2/5.3 Command Summary +AUTHOR: SSC Staff +SUBJECT: Pocket-sized book listing UNIX Systems 5.2 and 5.3 commands +PUBLISHER: SSC (Specialized Systems Consultants, Inc.) +DATE: 1989 (revised) +PAGES: 56 +ISBN: 0-916151-23-9 +APPROX_COST: $6.00 +KEYWORDS: UNIX system V, commands, pocket reference +SUGGESTED_BY: Phil Hughes fyl@ssc.wa.com +COMMENTS + Includes commands, options and explanations as well as + special sections on awk and sdb. + +TITLE: UNIX Shell Programming +AUTHOR: Kochan, Stephen G. +AUTHOR: Wood, Patrick H. +SUBJECT: Shell Programming +PUBLISHER: Hayden Book Company +DATE: 1985 +PAGES: 442 +ISBN: 0-8104-6309-1 +APPROX_COST: 24.95 +KEYWORDS: Bourne Shell, sh +COMMENTS + I own this book, but I rarely crack it open. I guess the main reason + is that I am still a Bourne-again shell user. For years I worked with + a variety of systems where one might find csh and/or ksh. However, + /bin/sh was the only common denominator. I find that most often I + refer to Kernighan and Pike for shell programming questions. However, + they don't address the C Shell (csh) or Korn Shell (ksh). This book + does offer a chapter on each. In addition, this book may be more + suited for a beginner than an experienced UNIX programmer. + +TITLE: UNIX System Administration Handbook +AUTHOR: Nemeth, Evi +AUTHOR: Snyder, Garth +AUTHOR: Seebass, Scott +SUBJECT: System Administration +PUBLISHER: Prentice Hall +ISBN: 0-13-933441-6 +DATE: 1989 +PAGES: 593 +APPROX_COST: 32.00 +KEYWORDS: SunOS, BSD, Administration +SUGGESTED_BY: Michael S. Cross <msc@ihc.att.com> +COMMENTS + { I'm recommending it for all of the people who get workstations + from us, and for all of the User Services people here -- an + added plus is that the programs listed are available by + anonymous ftp from the authors' home system. S.B.Bassett } + + The book does a pretty good job of explaining the differences + between the types of UNIX(R) systems and administering them. It's + also on the light or humorous side which is a definite plus. + +TITLE: UNIX System Command Summary for SVR4/Solaris 2.1 +AUTHOR: SSC +SUBJECT: UNIX: Solaris 2.x +PUBLISHER: SCC Inc. +DATE: 1992 +PAGES: 159 +ISBN: 0-916151-61-1 +APPROX_COST: 10.00 +KEYWORDS: Solaris, SVR4 +COMMENTS: + Pocket reference? Pocket Book! Here is alot of information + concisely placed in a pocket sized book and easy on the pocket + book. It is jam packed with information ranging from your + favorite options to adb, through NIS+, and on to vgrind and yacc. + It has alot of "pkginfo(1)"... + +TITLE: UNIX System Programming +AUTHOR: Haviland, Keith +AUTHOR: Salama, Ben +SUBJECT: Programming +PUBLISHER: Addison-Wesley +DATE: 1987 +PAGES: 339 +ISBN: 0-201-12919-1 +APPROX_COST: 27.95 +COMMENTS + Concentrates on the UNIX System call interface. + +TITLE: UNIX System Security +AUTHOR: Wood, Patrick H. +AUTHOR: Kochan, Stephen G. +SUBJECT: UNIX Security +PUBLISHER: Hayden Book Company +DATE: 1985 +PAGES: 299 +ISBN: 0-8104-6267-2 +APPROX_COST: 34.95 +KEYWORDS: Security +SUGGESTED_BY: Mitch Wright <mitch@hq.af.mil> +COMMENTS + -- From back cover + + Here is a practical guide to computer security on the UNIX system for + the user, administrator, or potential UNIX system buyer. It will + teach you everything you need to know ot make your system secure and + keep it that way. Topics covered include: + + - file and directory permissions + - password security + - how the setuid/gid permissions work and how to use them + - how the various security-related UNIX commands and functions work + - how to write secure programs + - different methods of data encryption -- including the government + standard DES algorithm -- and how secure they are + - data encryption over communication networks + - how to discover and plug potential security holes in your system + - how to periodically monitor your system to maintain security + + Also included is the complete source for several security auditing and + administration programs. + +TITLE: UNIX System V Bible +AUTHOR: Prata, Stephen +AUTHOR: Martin, Donald +AUTHOR: The Waite Group +SUBJECT: SYSV Reference +PUBLISHER: Howard Sams & Company +DATE: 1987 +PAGES: 516 +ISBN: 0-672-22562-X +APPROX_COST: 24.95 +COMMENTS + This is a comprehenisve reference for programmers working with the + UNIX operating system documentation, covering intermediate to advanced + level programming for professionals who have prior experience + programming in C or using UNIX. + +TITLE: The UNIX System V Environment +AUTHOR: Bourne, Steven R. +SUBJECT: Users Guide +PUBLISHER: Addison-Wesley +DATE: 1987 +PAGES: 378 +ISBN: 0-201-18484-2 +APPROX_COST: 26.95 +SUGGESTED_BY: Steen Hammerum +COMMENTS + Steen Hammerum Department of Chemistry, University of Copenhagen says: + "has been _very_ useful to me (proof: I'm on my second copy)" + +TITLE: UNIX System: Readings and Applications +AUTHOR: AT&T +SUBJECT: Reference +PUBLISHER: Prentice-Hall +DATE: 1987 +PAGES: <pages> +ISBN: 013-938532-0 (v1) +ISBN: 013-939845-7 (v2) +APPROX_COST: 19.00 each +COMMENTS + Vol 1: UNIX Time-Sharing System + Vol.2: The UNIX System + + These two volumes are reprints of the two volumes of the Bell + Labs Technical Journal (now AT&T Tech J.) that were devoted to UNIX: + Vol. 57, No. 6, Part 2, July-August, 1987, and + Vol. 63, No. 8, October, 1984. + +TITLE: Unix System Security +AUTHOR: Rik Farrow +SUBJECT: UNIX security +PUBLISHER: Addison-Wesley +DATE: 1991 +PAGES: 278 +ISBN: 0-201-57030-0 +APPROX_COST: 22.95 +KEYWORDS: Security +COMMENTS: + Farrow is editor-at-large for UNIXWorld magazine and also wrote + "Unix administration guide for System V". This book is well-done, + containing lots of examples of how to break and fix Unix security, + although a lot of it seems to be a rehash of material that's been + printed before. It's a worthwhile addition to any Unix + system admin's library. + +TITLE: Unix System Security - A Guide for Users and System Administrators +AUTHOR: Curry, David +SUBJECT: Security +PUBLISHER: Addison Wesley +DATE: 1992 +PAGES: +ISBN: 0-201-56327-4 +APPROX_COST: +KEYWORDS: UNIX security +SUGGESTED_BY: Rob Slade <roberts@decus.arc.ab.ca> +COMMENTS + What do you say about a computer security book that has a picture of a + cute little cartoon devil on the cover? + + Well, in this case, the cover hides a competent and fairly thorough + treatment of security on UNIX systems. Nothing terribly surprising, + but a step-by-step exploration of the various aspects of UNIX + security, potential threats, and suggestions to reduce the level of + vulnerability. + + The subtitle explains that the book is "A Guide for Users and System + Administrators" and the preface further provides that the attempt has + been made to provide sufficient information that administrators can + protect their systems, while not giving away details that can help + crackers. By and large the book succeeds. The book is clear and + simple enough that users (intelligent ones, anyway) should be able to + understand the concepts and need for security. System administrators + will find a fairly comprehensive overview of the topic. (Some areas, + such as the reading list, could use a bit more material, but there is, + at least, a "good start".) "Crackers" may find some help (such as the + password cracking program), but definitely won't be able to use this + as a "cookbook". + + copyright Robert M. Slade, 1993 BKCURRY.RVW 930802 + +TITLE: UNIX Text Processing +AUTHOR: Dougherty, Dale +AUTHOR: O'Reilly, Tim +SUBJECT: Text Processing +PUBLISHER: Hayden Books +DATE: 1987 +PAGES: 665 +ISBN: 0-672-46291-5 +APPROX_COST: 26.95 +SUGGESTED_BY: Mitch Wright <mitch@hq.af.mil> +COMMENTS + This is a MUST for all [nt]roff users. + +TITLE: The UNIX Text Processing System +AUTHOR: Christian, Kaare +SUBJECT: Text Processing +PUBLISHER: John Wiley & Sons, Inc. +DATE: 1987 +PAGES: 250 +ISBN: 0-471-85581-2 +APPROX_COST: 24.95 +SUGGESTED_BY: "Michael J. Chinni, SMCAR-CCS-E" <mchinni@PICA.ARMY.MIL> +COMMENTS + I have found this to be a very good guide to nroff, and the -mm + macros. It also covers the -ms macros, vi, eqn, tbl, refer, and pic + +TITLE: UNIX for Super-Users +AUTHOR: Foxley, Eric +SUBJECT: Users Guide +PUBLISHER: Addison-Wesley +DATE: 1985 +PAGES: 213 +ISBN: 0-201-14228-7 +APPROX_COST: 27.95 +KEYWORDS: SYSV + +TITLE: UNIX for the impatient +AUTHOR: Abrahams, Paul W. +AUTHOR: Larson, Bruce A. +SUBJECT: UNIX, patience +PUBLISHER: Addison Wesley +DATE: 1992 +PAGES: 559 +ISBN: 0-201-55703-7 +APPROX_COST: $26.95 +KEYWORDS: UNIX, Shell, X, Intro +SUGGESTED_BY: Lawrence P. O'Keefe, <okeefe@cns.nyu.edu> +COMMENTS: + + From the preface: "... an in-depth, comprehensive guide to + UNIX - a handbook you can use both as a manual to learn UNIX + and as a ready reference for fast answers to specific UNIX questions" + + Chapters: + Introduction + Concepts + Basic operations on files + Utility programs + Shells + Standard editors + The GNU Emacs editor + Data manipulation using filters + Sending and receiving mail + Communicating with remote computers + The X window system + Appendices: + Alphabetical summary of commands + Comparison of MS-DOS and UNIX + Resources + Glossary + + Lawrence says: + ``I find the book very useful, particularly the command summary + and the section on filters.'' + +TITLE: UNIX in a Nutshell (BSD) +AUTHOR: <author> +SUBJECT: Introduction +PUBLISHER: O'Reilly & Associates, Inc. +DATE: 1987 +PAGES: 272 +ISBN: 0-937175-20-X +APPROX_COST: 19.50 +KEYWORDS: Nutshell Handbook + +TITLE: UNIX in a Nutshell (System V) +AUTHOR: <author> +SUBJECT: Introduction +PUBLISHER: O'Reilly & Associates, Inc. +DATE: 1987 +PAGES: 296 +ISBN: 0-937175-19-6 +APPROX_COST: 19.50 +KEYWORDS: Nutshell Handbook + +TITLE: UNIX in a Nutshell: Desktop Quick Reference for SV & Solaris 2.0 +AUTHOR: Gilly, Daniel +AUTHOR: ORA Staff +SUBJECT: UNIX +PUBLISHER: O'Reilly and Associates +DATE: June 1992 +PAGES: 444 +ISBN: 1-56592-001-5 +APPROX_COST: $9.95 +KEYWORDS: UNIX, Solaris, SVR4 + + You may have seen UNIX quick reference guides, but you've never seen + anything like UNIX in a Nutshell. Not a scaled-down quick-reference + of common commands, UNIX in a Nutshell is a complete reference + containing all commands and options, along with generous descriptions + and examples that put the commands in context. For all but the + thorniest UNIX problems this one reference should be all the + documentation you need. + + Covers System V Releases 3 and 4 and Solaris 2.0. + +TITLE: UNIX, The Complete Reference +AUTHOR: Coffin, Stephen +SUBJECT: UNIX Reference +PUBLISHER: Osborne-McGraw Hill +DATE: 1988 +PAGES: 704 +ISBN: 0-07-881299-2 +APPROX_COST: 24.95 +COMMENTS + An inexpensive reference and guide to System V in a style + familiar to those from the micro world where OMH and QUE + have many best selling guides to Lotus, DOS, Word, etc. + +TITLE: Understanding and Using COFF +AUTHOR: Gircys, Gintaras R. +SUBJECT: Introduction +PUBLISHER: O'Reilly & Associates, Inc. +DATE: 1988 +PAGES: 196 +ISBN: 0-937175-31-5 +APPROX_COST: 21.95 +KEYWORDS: Nutshell Handbook +SUGGESTED_BY: Mitch Wright <mitch@hq.af.mil> +COMMENTS + -- From back cover + This handbook explains the COFF data structure and its manipulation. + + Contents include: + - The basics of COFF + - Assembley code relocation process + - COFF file headers + - Relocation structures + - The linking process + - The COFF system in UNIX + - Magic numbers + - The COFF symbolic debug system + - COFF and shared libraries + - Utilities and techniques for working with COFF files + - A sample program to manipulate COFF + + [ Source used in this book is available via ftp from UUNET ~mitch ] + +TITLE: Unix Administrations Guide for System V +AUTHOR: Thomas, Rebecca +AUTHOR: Farrow, Rik +SUBJECT: System Administration +PUBLISHER: Prentice-Hall +DATE: 1989 +PAGES: 636 +ISBN: 0-139-42889-5 +APPROX_COST: 34.95 +SUGGESTED_BY: Lars Tunkrans +COMMENTS + Bought this book last week, seems to me to be the most + comprehensive and fact-packed book on the subject I've ever seen. + +TITLE: UNIX Applications Programming Mastering the Shell +AUTHOR: Swartz, Ray +SUBJECT: Bourne Shell programming, grep, sed, awk, sort +PUBLISHER: SAMS, A Division of Macmillan Computer Publishing +DATE: 1990 +PAGES: 452 +ISBN: 0-672-22715-0 +LCCN: 90-61476 +APPROX_COST: 26.95 +KEYWORDS: Unix, Bourne shell programming, tools +SUGGESTED_BY: zwbm07@hou.amoco.com (Walter Moore) +COMMENTS + I find this book a VERY good primer and an excellent reference + book on Unix tools and shell programming. + +TITLE: The Unix Command Reference Guide +AUTHOR: Christian, Kaare +SUBJECT: Topically organized reference for about 50 Unix commands +PUBLISHER: John Wiley & Sons, Inc. +DATE: 1988 +PAGES: 361 +ISBN: 0-471-85580-4 PBK +APPROX_COST: 24.95 +COMMENTS + This book is a guide to the most useful Unix commands, organized + topically. It is used both as a handy reference, and as a quick start + guide for technically adept users who are starting to use the Unix + system. The book contains comprehensive sections on awk, sed, vi, and + the Bourne shell. There are many examples. + +TITLE: Unix Communications +AUTHOR: Anderson, Bart +AUTHOR: Costales, Barry +AUTHOR: Henderson, Harry +SUBJECT: Communication Reference +PUBLISHER: The Waite Group +DATE: 1991 +PAGES: 736 +ISBN: 0-672-22773-8 +APPROX_COST: 29.95 +KEYWORDS: UUCP, USENET +COMMENTS + Covers everything the end user needs to know about email, USENET + and UUCP. + +TITLE: The Unix Environment +AUTHOR: Walker, A. N. +SUBJECT: UNIX +PUBLISHER: John Wiley & Sons +DATE: 1984 +PAGES: 151 +ISBN: 0-471-90564-X +APPROX_COST: 20.40 +COMMENTS + An excellent user's introduction. I have a special affection for + this book, as it introduced me to the plural forms VAXen and Unices. + +TITLE: The Unix Operating System, Second Edition +AUTHOR: Christian, Kaare +SUBJECT: Comprehensive introduction to Unix +PUBLISHER: John Wiley & Sons, Inc. +DATE: 1988 +PAGES: 455 +ISBN: 0-471-84782-8 HBK +ISBN: 0-471-84781-X PBK +APPROX_COST: 24.95 +COMMENTS + This is the second edition of a widely used, widely translated + primeval Unix book. It is a comprehensive introductory book that goes + into more detail than most. While it is not a very good introduction + for people who will only use the system superficially, it is an + excellent introduction for those who plan to master the Unix system. + It includes sections on the most useful utilities, shell programming, + vi editing, and system internals. + +TITLE: Unix Power Utilities for Power Users +AUTHOR: Muster, John +AUTHOR: Birns, Peter +SUBJECT: Introduction to UNIX +PUBLISHER: MIS Press +DATE: 1989 +PAGES: 420 +ISBN: 1-55828-000-6 +APPROX_COST: 24.95 +COMMENTS + ** From Page 2... + + Overview of Contents + If you have the ability to log on the system, create, move, copy and + remove files, create and change directories, and issue basic shell + commands, you will be able to complete the exercises in these modules. + If you are more experienced, you may be able to proceed quickly + through part or all of Modules 2 and 3, and the introductory steps to + several of the other modules. + +TITLE: The UNIX Survival Guide +AUTHOR: Nichols, Elizabeth A. +AUTHOR: Balin, Sidney C. +AUTHOR: Nichols, Joseph C. +SUBJECT: Introduction to UNIX basics +PUBLISHER: Holt, Rinehart & Winston +DATE: 1987 +PAGES: 311 +ISBN: 0-03-000773-9 +SUGGESTED_BY: Andrew T. Young <aty@mintaka.sdsu.edu> +COMMENTS: + It contains good tutorial information for new owners of UNIX systems, + as well as for new users. There is a useful introduction to the nuts + and bolts of the file system, for example, as well as info on basic + commands, and a chapter on processes and signals. + +TITLE: Unix System Administration +AUTHOR: Fiedler, David +AUTHOR: Hunter, Bruce H. +SUBJECT: System Administration +PUBLISHER: Hayden Books (Howard Sams & Co) +DATE: 1986 +PAGES: 320 +ISBN: 0-8104-6289-3 +APPROX_COST: 24.94 +KEYWORDS: Administration +COMMENTS + -- From back cover -- + An essential guide for anyone who owns or operates a UNIX system. The + clear presentation and easy-to-follow style make it suitable for the + user who does not have a technical background. [...] + Using step-by-step guidelines for complex procedures, the book + includes information on: + - making back-ups + - configuring systems + - writing shell programs + - connecting a printer, a terminal, and other devices + - communicating with other systems + +TITLE: UNIX System V, Release 4 Administration +AUTHOR: Fiedler, David +AUTHOR: Hunter, Bruce H. +SUBJECT: System Administration +PUBLISHER: Hayden Books +DATE: 1992 +PAGES: 436 +ISBN: 0-672-22810-6 +APPROX_COST: 29.95 +KEYWORDS: Administration, SVR4 +COMMENTS + -- From back cover -- + UNIX(r) Sytem V Release 4 Administration, Second Editoin, starts with + a quick overview and shows you how to set up file systems, add and + remove users, and improve the security of your UNIX system. Explicit + troubleshooting charts help you find and solve typical system problems, + including those that invade networks. This updated edition also + presents expert UNIX coverage of mail and news systems, workstations, + X terminals, and PCs. You'll also find timesaving, ready-to-run + programs so that you can administrate your system with ease. + +TITLE: Unix for People +AUTHOR: Birns, Peter M. +AUTHOR: Brown, Patrick B. +AUTHOR: Muster, John C. +SUBJECT: Introduction +PUBLISHER: Prentice-Hall +DATE: 1985 +PAGES: 528 +ISBN: 0-13-937442-6 PBK +ISBN: 0-13-937459-0 HBK +APPROX_COST: 28.00 + +TITLE: Using the UNIX system +AUTHOR: Gauthier, Richard L. +SUBJECT: Introduction to UNIX +PUBLISHER: +DATE: 1981 +PAGES: 297 +ISBN: 0-8359-8164-9 HBK +ISBN: 0-8359-8162-2 PBK +COMMENTS + Introductory level book, extremely basic and easy reading. I read + this on a plane trip between Newark, NJ and Columbus, OH before I ever + worked seriously with UNIX. Unlike, Rebecca Thomas and Jean Yates + Tutorial style book this one does not require you to be sitting down + in front of a crt in order to derive benefit from it. + +TITLE: Using C on the UNIX system +AUTHOR: Curry, David A. +SUBJECT: C programming +PUBLISHER: O'Reilly & Associates, Inc. +DATE: 1989 +PAGES: 250 +ISBN: 0-937175-23-4 +APPROX_COST: 24.95 +KEYWORDS: C, UNIX +SUGGESTED_BY: Mitch Wright <mitch@hq.af.mil> +SUPPLIERS + E-mail: ... uunet!ora!nuts + Phone#: 1-800-338-NUTS +COMMENTS + This is a must for the Beginning UNIX programmer. + +TITLE: Using C with Curses, Lex and YACC +AUTHOR: Schreiner, Axel T. +SUBJECT: Programming +PUBLISHER: Prentice-Hall +DATE: 1990 +PAGES: 257 +ISBN: 0-13-932864-5 +APPROX_COST: 44.95 +KEYWORDS: C, Curses, Lex, YACC +COMMENTS: + -- From back cover -- + This book presents the development of programs that make extensive use + of curses and provides solutions to the typical problems encountered + when implementing full-screen applications with curses. + The book illustrates how to work in the Unix C environment: + + - how to build command languages with the compiler generatores lex and + yacc + - how to make portable full-screen dialogs with the curses library + - how to build symbol tables and manage variable-length argument lists + using C library functions + - how to manage program development with the make program + - how to manage multiple processes from a program and how to + communicate with them. + + Throughout the book the full source code of a major example is shown. + +TITLE: Using UUCP and USENET +AUTHOR: Todino, Grace +AUTHOR: Dougherty, Dale +SUBJECT: Introduction +PUBLISHER: O'Reilly & Associates, Inc. +DATE: 1990 +PAGES: 210 +ISBN: 0-937175-10-2 +APPROX_COST: 21.95 +KEYWORDS: Nutshell Handbook +SUGGESTED_BY: Mitch Wright <mitch@hq.af.mil> + +TITLE: UNIX for FORTRAN Programmers +AUTHOR: Loukides, Mike +SUBJECT: UNIX +DATE: <date> +PUBLISHER: O'Reilly and Associates +PAGES: 264 +ISBN: 0-937175-51-X +APPROX_COST: 24.95 +COMMENTS + This handbook minimizes the UNIX entry barrier, by providing + the serious scientific programmer with an introduction to + the UNIX operating system and its tools. + Assumes some knowledge of FORTRAN, but none of UNIX nor C. + +TITLE: UNIX/Xenix Text Processing Reference +AUTHOR: SSC Staff +SUBJECT: Pocket-sized reference card on nroff, troff, tbl, eqn and mm macros +PUBLISHER: SSC (Specialized Systems Consultants, Inc.) +DATE: 1987 +PAGES: 33 +ISBN: 0-916151-22-0 +APPROX_COST: $6.00 +KEYWORDS: troff, nroff, tbl, eqn, mm, text processing, pocket reference +SUGGESTED_BY: Phil Hughes fyl@ssc.wa.com + +TITLE: VI Reference +AUTHOR: SSC Staff +SUBJECT: Pocket-sized reference card on the VI editor +PUBLISHER: SSC (Specialized Systems Consultants, Inc.) +DATE: January, 1991 (revised) +PAGES: 10 +ISBN: 0-916151-41-7 +APPROX_COST: $3.00 +KEYWORDS: vi, pocket reference, UNIX +SUGGESTED_BY: Phil Hughes fyl@ssc.wa.com +COMMENTS + First published in 1984, updated regularly since then + +TITLE: VI Tutorial +AUTHOR: Frazier, Belinda +SUBJECT: Pocket-sized tutorial on the VI editor +PUBLISHER: SSC (Specialized Systems Consultants, Inc.) +DATE: January, 1992 (revised) +PAGES: 56 +ISBN: 0-916151-54-9 +APPROX_COST: $6.00 +KEYWORDS: vi, pocket tutorial, UNIX +SUGGESTED_BY: Phil Hughes fyl@ssc.wa.com +COMMENTS + Complements the SSC VI Reference + +TITLE: The Whole Internet User's Guide & Catalog +AUTHOR: Krol, Ed +SUBJECT: Use of the Internet +PUBLISHER: O'Reilly and Associates +DATE: September 1992 +PAGES: 397 +ISBN: 1-56592-025-2 +APPROX_COST: $24.95 +KEYWORDS: Internet, Archie, WAIS, Gopher +SUGGESTED_BY: Mitch Wright <mitch@oz.com> +COMMENTS + + [taken from ORA literature] + + A comprehensive introduction to the Internet, the international + network that includes virtually every major computer site in the world. + The Internet is a resource of almost unimaginable wealth. In addition + to electronic mail and news services, thousands of public archives, + databases, and other special services are available: everything from + space flight announcements to ski reports. This book is a comprehensive + introduction to what's available and how to find it. In addition to + electronic mail, file transfer, remote login, and network news, The + Whole Internet User's Guide pays special attention to some + new tools for helping you find information. Whether you're a + researcher, a student, or just someone who likes electronic mail, + this book will help you to explore what's possible. + + Also includes a pull-out quick-reference card. + + Be sure to see page 294! :-) + + +TITLE: Writing a Unix Device Driver +AUTHOR: Egan, Janet I. +AUTHOR: Teixeira, Thomas J. +SUBJECT: Programming +PUBLISHER: John Wiley & Sons. +DATE: 1988 +PAGES: 357 +ISBN: 0-471-62811-5, paperback: 0-471-62859-X +APPROX_COST: 24.95 +KEYWORDS: BSD, Xenix + +TITLE: X Window System Administrator's Guide +AUTHOR: Mui, Linda +AUTHOR: Pearce, Eric +SUBJECT: X, Admin +PUBLISHER: O'Reilly & Associates +DATE: October 1992 +PAGES: 372 +ISBN: 0-937175-83-8 +APPROX_COST: 29.95 +KEYWORDS: X11R4, X11R5 +COMMENTS: + Ever wonder what is involved in setting up and maintaining X. + Wonder no more... buy this book! + +TITLE: The X Window System in a Nutshell +AUTHOR: Cutler, Ellie +AUTHOR: Gilly, Daniel +AUTHOR: O'Reilly, Tim +PUBLISHER: O'Reilly & Associates +DATE: 1993 +PAGES: 424 +ISBN: 1-56592-017-1 +APPROX_COST: 9.95 +KEYWORDS: X +COMMENTS: + From ORA mailing + We have lowered the price of this book to $9.95 from $24.95. + It contains essential information in a boiled-down quick-reference + format that makes it easy to find the answers needed most often: + + - Command line options and resources for the standard MIT X clients. + - Calling sequence for all Xlib and Xt functions and macros. + - Detailed description of structures, enums, and other X data types + used as arguments or return values in Xlib or Xt functions. + - Description of the code inside a basic widget. + - Quick reference to the event structures. + - Font name syntax, color names, resource file and translations + table syntax, and cursors. + - Xlib and Xt error messages. + + The descriptions of the functions have been expanded and clarified, + with improved cross-referencing to important related functions. + Includes material on Xcms and the internationalization features of R5. + +TITLE: X Window System User's Guide +AUTHOR: Quercia, Valerie +AUTHOR: O'Reilly, Tim +SUBJECT: X +PUBLISHER: O'Reilly & Associates +DATE: May 1993 +PAGES: 752 +ISBN: 1-56592-014-7 +APPROX_COST: 34.95 +KEYWORDS: X11R5 +COMMENTS: + X is just too darn configurable. And why does the client/server + seem so strange. This book will help you wrestle with those + concepts and help you create a usable X environment. + It is also an excellent guide for admins -- just point to it on + your desk when some user comes up to you and asks ``how do I...'' + +TITLE: The Xenix Command Reference Guide +AUTHOR: Christian, Kaare +AUTHOR: Richter, Susan +SUBJECT: Topically organized reference for about 50 Xenix commands +PUBLISHER: John Wiley & Sons, Inc. +DATE: 1988 +PAGES: 420 +ISBN: 0-471-61707-5 (pbk) +APPROX_COST: 24.95 +COMMENTS + This book is a guide to the most useful Xenix commands, organized + topically. It is used both as a handy reference, and as a quick start + guide for technically adept users who are starting to use the Xenix + system. The book contains comprehensive sections on awk, sed, vi, the + Bourne shell, and system administration. There are many examples. + +TITLE: Xenix System V Command Summary +AUTHOR: SSC Staff +SUBJECT: Pocket-sized book listing SCO Xenix System V commands +PUBLISHER: SSC (Specialized Systems Consultants, Inc.) +DATE: 1989 +PAGES: 60 +ISBN: 0-916151-35-2 +APPROX_COST: $6.00 +KEYWORDS: vi, pocket reference +SUGGESTED_BY: Phil Hughes fyl@ssc.wa.com +COMMENTS + Includes commands, options and explanations as well as special + sections on awk, C Shell and sdb. + +TITLE: The Z-Mail Handbook: 3 Interfaces for E-mail +AUTHOR: Nelson, Hanna +SUBJECT: Electronic mail +PUBLISHER: O'Reilly and Associates +DATE: <year> +PAGES: 462 +ISBN: 0-937175-76-5 +APPROX_COST: 29.95 +KEYWORDS: E-mail, Z-mail, mush +SUGGESTED_BY: <person> <email-addr> +COMMENTS: + Z-Mail is a superset of the widely-used public-domain program, + Mush. Z-Mail runs on UNIX terminals or on graphic workstations + running the X Window System, and even supports multimedia + attachments (so you can mail anything that you can store on disk). + This is the complete guide to this powerful mail program. Also + covers Mush. + +TITLE: Zen and the Art of the Internet, A Beginner's Guide +AUTHOR: Kehoe, Brendan P. +SUBJECT: networking +PUBLISHER: +DATE: 1992 +PAGES: 113 +ISBN: +APPROX_COST: $22.00 +KEYWORDS: network, internet +COMMENTS: + A fun introduction and quick-access reference for once and future + travelers on the Internet. This complete guide covers searching + databases, sending and receiving e-mail, accessing Usenet news, + remote and commercial information services, using the FTP, and + much more. + +TITLE: ** Publishers ** +SUBJECT: Suppliers +COMMENTS + >> Tell 'em Mitch sent ya. :-) + + ---------------------------------------------------------- + + Addison-Wesley Publishing Co. + + 1 Jacob Way + Reading, MA 01867-9984 + 800-527-5210 + 617-944-3700 + + 5851 Guion Road + Indianapolis, IN 46254 + 800-447-2226 + + ---------------------------------------------------------- + + O'Reilly and Associates + 103 Morris Street, Suite A + Sebastopol, CA 95472 + ** (800) 998-9938 ** + Local/Overseas: 1-707-829-0515 (7am-5pm PST) + FAX: (707) 829-0104 + E-mail: nuts@ora.com + uunet!ora!nuts + + Gopher: gopher.ora.com + WWW users can use the following http addr: "gopher://gopher.ora.com" + + ---------------------------------------------------------- + + SSC + P.O. Box 55549 + Seattle, WA 98155 + (206) FOR-UNIX / (206)527-3385 + FAX: (206) 527-2806 + E-mail: sales@ssc.wa.com + + ---------------------------------------------------------- + + QED Publishing Group + PO Box 812070 + Wellesley, MA 02181-0013 + tel: 617-237-5656-, 800-343-4848 + fax: 627-235-0826 + e-mail: 76620.2720@compuserve.com + + ---------------------------------------------------------- + + As a note, I'm only including publisher names, addresses, ... + IFF they have a phone number or E-mail address for ordering. + +Local Variables: +mode: outline +selective-display-ellipses: nil +outline-regexp: "TITLE: " +eval: (hide-body) +End: diff --git a/reference/C/CONTRIB/intro.html b/reference/C/CONTRIB/intro.html new file mode 100755 index 0000000..018d1ec --- /dev/null +++ b/reference/C/CONTRIB/intro.html @@ -0,0 +1,200 @@ +<html> +<head> +<Title>Internet References + + + +
+

Internet References.

+
+

+ +Where possible these links are to other sites. Some of the +references are uncompressed or de-archived copies of the originals. + +

+ + +
+

Mirror Sites

+
+This page is available at the following sites. I would like to thank +the administrators of these sites for hosting the guide. +

+

o +
+USA - Maintained by Gary Greenburg. +

+ +

o +
+Maintained by Javier Gutierrez on a IRIX 5.2 server. +

+ +

o +
+Maintained by Javier Gutierrez on a IRIX 5.2 server. +

+ +

o +
+French site. +

+ +

o +
+English site. +

+ +

o +
+Bernd Petrovitsch. +

+ +

o +
+The latest home site. The home site has moved three times in three +years. Maybe this will be the final resting place :-) +

+ +

+
+ +

+ +C Tutorials on the net. + +

+

+ + +

o +
David Marshall's 'Programming +in C' tutorial +

+ +

o +
'C' course from Chris Sawtell. +

+ +

o +
+'C Programming' from Steve Holmes.
+University of Strathclyde Computer Centre.
+Curran Building.
+100 Cathedral Street.
+Glasgow. +

+ + +

o + +
Tim Loves +'C for Programmers'. This +is a LARGE postscript document. Only download if you have a Postscript +viewer or printer. +

+

o +
+Tim Loves documentation in HTML form. +

+

o +
Introduction to C +Programming by Marshall Brian +

+


+

C Reference documents.

+
o +ANSI C +Programming from Phil Willis +

+


+

C Resources.

+
o + +Martin Brown's Hot List + +

+

o +C Language Resource List + +

+


+

Items of interest from the net.

+ +
o +
Snippets - program examples. Compiled by Bob Stout. +

+ +

o +
Learn C/C++ +A comprehensive list of C related links maintained by Vinny Carpenter. +

+ +

o +
C news group. Catch up on C related topics. +

+ +

o +
C frequently-asked questions (FAQ) +maintained by Steve Summit. + +

+HTML version of Steves FAQ + +

+ +

o + +
Books list (mostly C related) compiled by Mitch +Wright. +

+ + +

o + +
Copies of the programs provided in the following O'Reilly Nutshell books. + +
+ + +
+

Compilers

+
+
+
o +
Pacific C compiler for MS-DOS +
+

+ + +

+ +


+

+

+ + + + +
+ Top + + Master Index + + Keywords + + Functions +
+
+

+


+
Martin Leslie +

+ + -- cgit v1.2.3-54-g00ecf