Move tons of stuff into oldstuff/
This commit is contained in:
19
oldstuff/djtut/Pipfile
Normal file
19
oldstuff/djtut/Pipfile
Normal file
@@ -0,0 +1,19 @@
|
||||
[[source]]
|
||||
name = "pypi"
|
||||
url = "https://pypi.org/simple"
|
||||
verify_ssl = true
|
||||
|
||||
[dev-packages]
|
||||
black = "*"
|
||||
pytest = "*"
|
||||
pytest-django = "*"
|
||||
|
||||
[packages]
|
||||
Django = "<2.0"
|
||||
psycopg2 = "<2.8"
|
||||
|
||||
[requires]
|
||||
python_version = "3.7"
|
||||
|
||||
[pipenv]
|
||||
allow_prereleases = true
|
248
oldstuff/djtut/Pipfile.lock
generated
Normal file
248
oldstuff/djtut/Pipfile.lock
generated
Normal file
@@ -0,0 +1,248 @@
|
||||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "b34be6918d1424822217ca7656f0c09eae51b584a40c8a902cc0d589db10a1b8"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {
|
||||
"python_version": "3.7"
|
||||
},
|
||||
"sources": [
|
||||
{
|
||||
"name": "pypi",
|
||||
"url": "https://pypi.org/simple",
|
||||
"verify_ssl": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"default": {
|
||||
"django": {
|
||||
"hashes": [
|
||||
"sha256:014e3392058d94f40569206a24523ce254d55ad2f9f46c6550b0fe2e4f94cf3f",
|
||||
"sha256:4200aefb6678019a0acf0005cd14cfce3a5e6b9b90d06145fcdd2e474ad4329c"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==1.11.29"
|
||||
},
|
||||
"psycopg2": {
|
||||
"hashes": [
|
||||
"sha256:02445ebbb3a11a3fe8202c413d5e6faf38bb75b4e336203ee144ca2c46529f94",
|
||||
"sha256:0e9873e60f98f0c52339abf8f0339d1e22bfe5aae0bcf7aabd40c055175035ec",
|
||||
"sha256:1148a5eb29073280bf9057c7fc45468592c1bb75a28f6df1591adb93c8cb63d0",
|
||||
"sha256:259a8324e109d4922b0fcd046e223e289830e2568d6f4132a3702439e5fd532b",
|
||||
"sha256:28dffa9ed4595429e61bacac41d3f9671bb613d1442ff43bcbec63d4f73ed5e8",
|
||||
"sha256:314a74302d4737a3865d40ea50e430ce1543c921ba10f39d562e807cfe2edf2a",
|
||||
"sha256:36b60201b6d215d7658a71493fdf6bd5e60ad9a0cffed39906627ff9f4f3afd3",
|
||||
"sha256:3f9d532bce54c4234161176ff3b8688ff337575ca441ea27597e112dfcd0ee0c",
|
||||
"sha256:5d222983847b40af989ad96c07fc3f07e47925e463baa5de716be8f805b41d9b",
|
||||
"sha256:6757a6d2fc58f7d8f5d471ad180a0bd7b4dd3c7d681f051504fbea7ae29c8d6f",
|
||||
"sha256:6a0e0f1e74edb0ab57d89680e59e7bfefad2bfbdf7c80eb38304d897d43674bb",
|
||||
"sha256:6ca703ccdf734e886a1cf53eb702261110f6a8b0ed74bcad15f1399f74d3f189",
|
||||
"sha256:8513b953d8f443c446aa79a4cc8a898bd415fc5e29349054f03a7d696d495542",
|
||||
"sha256:9262a5ce2038570cb81b4d6413720484cb1bc52c064b2f36228d735b1f98b794",
|
||||
"sha256:97441f851d862a0c844d981cbee7ee62566c322ebb3d68f86d66aa99d483985b",
|
||||
"sha256:a07feade155eb8e69b54dd6774cf6acf2d936660c61d8123b8b6b1f9247b67d6",
|
||||
"sha256:a9b9c02c91b1e3ec1f1886b2d0a90a0ea07cc529cb7e6e472b556bc20ce658f3",
|
||||
"sha256:ae88216f94728d691b945983140bf40d51a1ff6c7fe57def93949bf9339ed54a",
|
||||
"sha256:b360ffd17659491f1a6ad7c928350e229c7b7bd83a2b922b6ee541245c7a776f",
|
||||
"sha256:b4221957ceccf14b2abdabef42d806e791350be10e21b260d7c9ce49012cc19e",
|
||||
"sha256:b90758e49d5e6b152a460d10b92f8a6ccf318fcc0ee814dcf53f3a6fc5328789",
|
||||
"sha256:c669ea986190ed05fb289d0c100cc88064351f2b85177cbfd3564c4f4847d18c",
|
||||
"sha256:d1b61999d15c79cf7f4f7cc9021477aef35277fc52452cf50fd13b713c84424d",
|
||||
"sha256:de7bb043d1adaaf46e38d47e7a5f703bb3dab01376111e522b07d25e1a79c1e1",
|
||||
"sha256:e393568e288d884b94d263f2669215197840d097c7e5b0acd1a51c1ea7d1aba8",
|
||||
"sha256:ed7e0849337bd37d89f2c2b0216a0de863399ee5d363d31b1e5330a99044737b",
|
||||
"sha256:f153f71c3164665d269a5d03c7fa76ba675c7a8de9dc09a4e2c2cdc9936a7b41",
|
||||
"sha256:f1fb5a8427af099beb7f65093cbdb52e021b8e6dbdfaf020402a623f4181baf5",
|
||||
"sha256:f36b333e9f86a2fba960c72b90c34be6ca71819e300f7b1fc3d2b0f0b2c546cd",
|
||||
"sha256:f4526d078aedd5187d0508aa5f9a01eae6a48a470ed678406da94b4cd6524b7e"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==2.7.7"
|
||||
},
|
||||
"pytz": {
|
||||
"hashes": [
|
||||
"sha256:1c557d7d0e871de1f5ccd5833f60fb2550652da6be2693c1e02300743d21500d",
|
||||
"sha256:b02c06db6cf09c12dd25137e563b31700d3b80fcc4ad23abb7a315f2789819be"
|
||||
],
|
||||
"version": "==2019.3"
|
||||
}
|
||||
},
|
||||
"develop": {
|
||||
"appdirs": {
|
||||
"hashes": [
|
||||
"sha256:9e5896d1372858f8dd3344faf4e5014d21849c756c8d5701f78f8a103b372d92",
|
||||
"sha256:d8b24664561d0d34ddfaec54636d502d7cea6e29c3eaf68f3df6180863e2166e"
|
||||
],
|
||||
"version": "==1.4.3"
|
||||
},
|
||||
"attrs": {
|
||||
"hashes": [
|
||||
"sha256:08a96c641c3a74e44eb59afb61a24f2cb9f4d7188748e76ba4bb5edfa3cb7d1c",
|
||||
"sha256:f7b7ce16570fe9965acd6d30101a28f62fb4a7f9e926b3bbc9b61f8b04247e72"
|
||||
],
|
||||
"version": "==19.3.0"
|
||||
},
|
||||
"black": {
|
||||
"hashes": [
|
||||
"sha256:1b30e59be925fafc1ee4565e5e08abef6b03fe455102883820fe5ee2e4734e0b",
|
||||
"sha256:c2edb73a08e9e0e6f65a0e6af18b059b8b1cdd5bef997d7a0b181df93dc81539"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==19.10b0"
|
||||
},
|
||||
"click": {
|
||||
"hashes": [
|
||||
"sha256:8a18b4ea89d8820c5d0c7da8a64b2c324b4dabb695804dbfea19b9be9d88c0cc",
|
||||
"sha256:e345d143d80bf5ee7534056164e5e112ea5e22716bbb1ce727941f4c8b471b9a"
|
||||
],
|
||||
"version": "==7.1.1"
|
||||
},
|
||||
"importlib-metadata": {
|
||||
"hashes": [
|
||||
"sha256:06f5b3a99029c7134207dd882428a66992a9de2bef7c2b699b5641f9886c3302",
|
||||
"sha256:b97607a1a18a5100839aec1dc26a1ea17ee0d93b20b0f008d80a5a050afb200b"
|
||||
],
|
||||
"markers": "python_version < '3.8'",
|
||||
"version": "==1.5.0"
|
||||
},
|
||||
"more-itertools": {
|
||||
"hashes": [
|
||||
"sha256:5dd8bcf33e5f9513ffa06d5ad33d78f31e1931ac9a18f33d37e77a180d393a7c",
|
||||
"sha256:b1ddb932186d8a6ac451e1d95844b382f55e12686d51ca0c68b6f61f2ab7a507"
|
||||
],
|
||||
"version": "==8.2.0"
|
||||
},
|
||||
"packaging": {
|
||||
"hashes": [
|
||||
"sha256:3c292b474fda1671ec57d46d739d072bfd495a4f51ad01a055121d81e952b7a3",
|
||||
"sha256:82f77b9bee21c1bafbf35a84905d604d5d1223801d639cf3ed140bd651c08752"
|
||||
],
|
||||
"version": "==20.3"
|
||||
},
|
||||
"pathspec": {
|
||||
"hashes": [
|
||||
"sha256:163b0632d4e31cef212976cf57b43d9fd6b0bac6e67c26015d611a647d5e7424",
|
||||
"sha256:562aa70af2e0d434367d9790ad37aed893de47f1693e4201fd1d3dca15d19b96"
|
||||
],
|
||||
"version": "==0.7.0"
|
||||
},
|
||||
"pluggy": {
|
||||
"hashes": [
|
||||
"sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0",
|
||||
"sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d"
|
||||
],
|
||||
"version": "==0.13.1"
|
||||
},
|
||||
"py": {
|
||||
"hashes": [
|
||||
"sha256:5e27081401262157467ad6e7f851b7aa402c5852dbcb3dae06768434de5752aa",
|
||||
"sha256:c20fdd83a5dbc0af9efd622bee9a5564e278f6380fffcacc43ba6f43db2813b0"
|
||||
],
|
||||
"version": "==1.8.1"
|
||||
},
|
||||
"pyparsing": {
|
||||
"hashes": [
|
||||
"sha256:4c830582a84fb022400b85429791bc551f1f4871c33f23e44f353119e92f969f",
|
||||
"sha256:c342dccb5250c08d45fd6f8b4a559613ca603b57498511740e65cd11a2e7dcec"
|
||||
],
|
||||
"version": "==2.4.6"
|
||||
},
|
||||
"pytest": {
|
||||
"hashes": [
|
||||
"sha256:0e5b30f5cb04e887b91b1ee519fa3d89049595f428c1db76e73bd7f17b09b172",
|
||||
"sha256:84dde37075b8805f3d1f392cc47e38a0e59518fb46a431cfdaf7cf1ce805f970"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==5.4.1"
|
||||
},
|
||||
"pytest-django": {
|
||||
"hashes": [
|
||||
"sha256:456fa6854d04ee625d6bbb8b38ca2259e7040a6f93333bfe8bc8159b7e987203",
|
||||
"sha256:489b904f695f9fb880ce591cf5a4979880afb467763b1f180c07574554bdfd26"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==3.8.0"
|
||||
},
|
||||
"regex": {
|
||||
"hashes": [
|
||||
"sha256:01b2d70cbaed11f72e57c1cfbaca71b02e3b98f739ce33f5f26f71859ad90431",
|
||||
"sha256:046e83a8b160aff37e7034139a336b660b01dbfe58706f9d73f5cdc6b3460242",
|
||||
"sha256:113309e819634f499d0006f6200700c8209a2a8bf6bd1bdc863a4d9d6776a5d1",
|
||||
"sha256:200539b5124bc4721247a823a47d116a7a23e62cc6695744e3eb5454a8888e6d",
|
||||
"sha256:25f4ce26b68425b80a233ce7b6218743c71cf7297dbe02feab1d711a2bf90045",
|
||||
"sha256:269f0c5ff23639316b29f31df199f401e4cb87529eafff0c76828071635d417b",
|
||||
"sha256:5de40649d4f88a15c9489ed37f88f053c15400257eeb18425ac7ed0a4e119400",
|
||||
"sha256:7f78f963e62a61e294adb6ff5db901b629ef78cb2a1cfce3cf4eeba80c1c67aa",
|
||||
"sha256:82469a0c1330a4beb3d42568f82dffa32226ced006e0b063719468dcd40ffdf0",
|
||||
"sha256:8c2b7fa4d72781577ac45ab658da44c7518e6d96e2a50d04ecb0fd8f28b21d69",
|
||||
"sha256:974535648f31c2b712a6b2595969f8ab370834080e00ab24e5dbb9d19b8bfb74",
|
||||
"sha256:99272d6b6a68c7ae4391908fc15f6b8c9a6c345a46b632d7fdb7ef6c883a2bbb",
|
||||
"sha256:9b64a4cc825ec4df262050c17e18f60252cdd94742b4ba1286bcfe481f1c0f26",
|
||||
"sha256:9e9624440d754733eddbcd4614378c18713d2d9d0dc647cf9c72f64e39671be5",
|
||||
"sha256:9ff16d994309b26a1cdf666a6309c1ef51ad4f72f99d3392bcd7b7139577a1f2",
|
||||
"sha256:b33ebcd0222c1d77e61dbcd04a9fd139359bded86803063d3d2d197b796c63ce",
|
||||
"sha256:bba52d72e16a554d1894a0cc74041da50eea99a8483e591a9edf1025a66843ab",
|
||||
"sha256:bed7986547ce54d230fd8721aba6fd19459cdc6d315497b98686d0416efaff4e",
|
||||
"sha256:c7f58a0e0e13fb44623b65b01052dae8e820ed9b8b654bb6296bc9c41f571b70",
|
||||
"sha256:d58a4fa7910102500722defbde6e2816b0372a4fcc85c7e239323767c74f5cbc",
|
||||
"sha256:f1ac2dc65105a53c1c2d72b1d3e98c2464a133b4067a51a3d2477b28449709a0"
|
||||
],
|
||||
"version": "==2020.2.20"
|
||||
},
|
||||
"six": {
|
||||
"hashes": [
|
||||
"sha256:236bdbdce46e6e6a3d61a337c0f8b763ca1e8717c03b369e87a7ec7ce1319c0a",
|
||||
"sha256:8f3cd2e254d8f793e7f3d6d9df77b92252b52637291d0f0da013c76ea2724b6c"
|
||||
],
|
||||
"version": "==1.14.0"
|
||||
},
|
||||
"toml": {
|
||||
"hashes": [
|
||||
"sha256:229f81c57791a41d65e399fc06bf0848bab550a9dfd5ed66df18ce5f05e73d5c",
|
||||
"sha256:235682dd292d5899d361a811df37e04a8828a5b1da3115886b73cf81ebc9100e"
|
||||
],
|
||||
"version": "==0.10.0"
|
||||
},
|
||||
"typed-ast": {
|
||||
"hashes": [
|
||||
"sha256:0666aa36131496aed8f7be0410ff974562ab7eeac11ef351def9ea6fa28f6355",
|
||||
"sha256:0c2c07682d61a629b68433afb159376e24e5b2fd4641d35424e462169c0a7919",
|
||||
"sha256:249862707802d40f7f29f6e1aad8d84b5aa9e44552d2cc17384b209f091276aa",
|
||||
"sha256:24995c843eb0ad11a4527b026b4dde3da70e1f2d8806c99b7b4a7cf491612652",
|
||||
"sha256:269151951236b0f9a6f04015a9004084a5ab0d5f19b57de779f908621e7d8b75",
|
||||
"sha256:4083861b0aa07990b619bd7ddc365eb7fa4b817e99cf5f8d9cf21a42780f6e01",
|
||||
"sha256:498b0f36cc7054c1fead3d7fc59d2150f4d5c6c56ba7fb150c013fbc683a8d2d",
|
||||
"sha256:4e3e5da80ccbebfff202a67bf900d081906c358ccc3d5e3c8aea42fdfdfd51c1",
|
||||
"sha256:6daac9731f172c2a22ade6ed0c00197ee7cc1221aa84cfdf9c31defeb059a907",
|
||||
"sha256:715ff2f2df46121071622063fc7543d9b1fd19ebfc4f5c8895af64a77a8c852c",
|
||||
"sha256:73d785a950fc82dd2a25897d525d003f6378d1cb23ab305578394694202a58c3",
|
||||
"sha256:8c8aaad94455178e3187ab22c8b01a3837f8ee50e09cf31f1ba129eb293ec30b",
|
||||
"sha256:8ce678dbaf790dbdb3eba24056d5364fb45944f33553dd5869b7580cdbb83614",
|
||||
"sha256:aaee9905aee35ba5905cfb3c62f3e83b3bec7b39413f0a7f19be4e547ea01ebb",
|
||||
"sha256:bcd3b13b56ea479b3650b82cabd6b5343a625b0ced5429e4ccad28a8973f301b",
|
||||
"sha256:c9e348e02e4d2b4a8b2eedb48210430658df6951fa484e59de33ff773fbd4b41",
|
||||
"sha256:d205b1b46085271b4e15f670058ce182bd1199e56b317bf2ec004b6a44f911f6",
|
||||
"sha256:d43943ef777f9a1c42bf4e552ba23ac77a6351de620aa9acf64ad54933ad4d34",
|
||||
"sha256:d5d33e9e7af3b34a40dc05f498939f0ebf187f07c385fd58d591c533ad8562fe",
|
||||
"sha256:fc0fea399acb12edbf8a628ba8d2312f583bdbdb3335635db062fa98cf71fca4",
|
||||
"sha256:fe460b922ec15dd205595c9b5b99e2f056fd98ae8f9f56b888e7a17dc2b757e7"
|
||||
],
|
||||
"version": "==1.4.1"
|
||||
},
|
||||
"wcwidth": {
|
||||
"hashes": [
|
||||
"sha256:8fd29383f539be45b20bd4df0dc29c20ba48654a41e661925e612311e9f3c603",
|
||||
"sha256:f28b3e8a6483e5d49e7f8949ac1a78314e740333ae305b4ba5defd3e74fb37a8"
|
||||
],
|
||||
"version": "==0.1.8"
|
||||
},
|
||||
"zipp": {
|
||||
"hashes": [
|
||||
"sha256:aa36550ff0c0b7ef7fa639055d797116ee891440eac1a56f378e2d3179e0320b",
|
||||
"sha256:c599e4d75c98f6798c509911d08a22e6c021d074469042177c8c86fb92eefd96"
|
||||
],
|
||||
"version": "==3.1.0"
|
||||
}
|
||||
}
|
||||
}
|
22
oldstuff/djtut/mysite/manage.py
Executable file
22
oldstuff/djtut/mysite/manage.py
Executable file
@@ -0,0 +1,22 @@
|
||||
#!/usr/bin/env python
|
||||
import os
|
||||
import sys
|
||||
|
||||
if __name__ == "__main__":
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings")
|
||||
try:
|
||||
from django.core.management import execute_from_command_line
|
||||
except ImportError:
|
||||
# The above import may fail for some other reason. Ensure that the
|
||||
# issue is really that Django is missing to avoid masking other
|
||||
# exceptions on Python 2.
|
||||
try:
|
||||
import django
|
||||
except ImportError:
|
||||
raise ImportError(
|
||||
"Couldn't import Django. Are you sure it's installed and "
|
||||
"available on your PYTHONPATH environment variable? Did you "
|
||||
"forget to activate a virtual environment?"
|
||||
)
|
||||
raise
|
||||
execute_from_command_line(sys.argv)
|
0
oldstuff/djtut/mysite/mysite/__init__.py
Normal file
0
oldstuff/djtut/mysite/mysite/__init__.py
Normal file
66
oldstuff/djtut/mysite/mysite/settings.py
Normal file
66
oldstuff/djtut/mysite/mysite/settings.py
Normal file
@@ -0,0 +1,66 @@
|
||||
import os
|
||||
|
||||
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
SECRET_KEY = "rbkosjwn!o^)&kb-fr^3^+y60bbz^76f#jt_7a%n1pt8jjd%bv"
|
||||
DEBUG = True
|
||||
ALLOWED_HOSTS = []
|
||||
INSTALLED_APPS = [
|
||||
"polls.apps.PollsConfig",
|
||||
"django.contrib.admin",
|
||||
"django.contrib.auth",
|
||||
"django.contrib.contenttypes",
|
||||
"django.contrib.sessions",
|
||||
"django.contrib.messages",
|
||||
"django.contrib.staticfiles",
|
||||
]
|
||||
MIDDLEWARE = [
|
||||
"django.middleware.security.SecurityMiddleware",
|
||||
"django.contrib.sessions.middleware.SessionMiddleware",
|
||||
"django.middleware.common.CommonMiddleware",
|
||||
"django.middleware.csrf.CsrfViewMiddleware",
|
||||
"django.contrib.auth.middleware.AuthenticationMiddleware",
|
||||
"django.contrib.messages.middleware.MessageMiddleware",
|
||||
"django.middleware.clickjacking.XFrameOptionsMiddleware",
|
||||
]
|
||||
ROOT_URLCONF = "mysite.urls"
|
||||
TEMPLATES = [
|
||||
{
|
||||
"BACKEND": "django.template.backends.django.DjangoTemplates",
|
||||
"DIRS": [],
|
||||
"APP_DIRS": True,
|
||||
"OPTIONS": {
|
||||
"context_processors": [
|
||||
"django.template.context_processors.debug",
|
||||
"django.template.context_processors.request",
|
||||
"django.contrib.auth.context_processors.auth",
|
||||
"django.contrib.messages.context_processors.messages",
|
||||
],
|
||||
},
|
||||
},
|
||||
]
|
||||
WSGI_APPLICATION = "mysite.wsgi.application"
|
||||
DATABASES = {
|
||||
"default": {
|
||||
"ENGINE": "django.db.backends.postgresql",
|
||||
"NAME": "mysite",
|
||||
"USER": "mysite",
|
||||
"HOST": "localhost",
|
||||
"PORT": "5432",
|
||||
"PASSWORD": "notsecurelol",
|
||||
},
|
||||
"test": {"ENGINE": "django.db.backends.sqlite3", "NAME": "test-mysite.sqlite3",},
|
||||
}
|
||||
AUTH_PASSWORD_VALIDATORS = [
|
||||
{
|
||||
"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator",
|
||||
},
|
||||
{"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator",},
|
||||
{"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator",},
|
||||
{"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator",},
|
||||
]
|
||||
LANGUAGE_CODE = "en-us"
|
||||
TIME_ZONE = "UTC"
|
||||
USE_I18N = True
|
||||
USE_L10N = True
|
||||
USE_TZ = True
|
||||
STATIC_URL = "/static/"
|
7
oldstuff/djtut/mysite/mysite/urls.py
Normal file
7
oldstuff/djtut/mysite/mysite/urls.py
Normal file
@@ -0,0 +1,7 @@
|
||||
from django.conf.urls import include, url
|
||||
from django.contrib import admin
|
||||
|
||||
urlpatterns = [
|
||||
url("^polls/", include("polls.urls")),
|
||||
url("^admin/", admin.site.urls),
|
||||
]
|
16
oldstuff/djtut/mysite/mysite/wsgi.py
Normal file
16
oldstuff/djtut/mysite/mysite/wsgi.py
Normal file
@@ -0,0 +1,16 @@
|
||||
"""
|
||||
WSGI config for mysite project.
|
||||
|
||||
It exposes the WSGI callable as a module-level variable named ``application``.
|
||||
|
||||
For more information on this file, see
|
||||
https://docs.djangoproject.com/en/1.11/howto/deployment/wsgi/
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
from django.core.wsgi import get_wsgi_application
|
||||
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings")
|
||||
|
||||
application = get_wsgi_application()
|
0
oldstuff/djtut/mysite/polls/__init__.py
Normal file
0
oldstuff/djtut/mysite/polls/__init__.py
Normal file
5
oldstuff/djtut/mysite/polls/admin.py
Normal file
5
oldstuff/djtut/mysite/polls/admin.py
Normal file
@@ -0,0 +1,5 @@
|
||||
from django.contrib import admin
|
||||
|
||||
from .models import Question
|
||||
|
||||
admin.site.register(Question)
|
5
oldstuff/djtut/mysite/polls/apps.py
Normal file
5
oldstuff/djtut/mysite/polls/apps.py
Normal file
@@ -0,0 +1,5 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class PollsConfig(AppConfig):
|
||||
name = "polls"
|
38
oldstuff/djtut/mysite/polls/migrations/0001_initial.py
Normal file
38
oldstuff/djtut/mysite/polls/migrations/0001_initial.py
Normal file
@@ -0,0 +1,38 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.11.29 on 2020-03-14 01:39
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Choice',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('choice_text', models.CharField(max_length=200)),
|
||||
('votes', models.IntegerField(default=0)),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Question',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('question_text', models.CharField(max_length=200)),
|
||||
('pub_date', models.DateTimeField(verbose_name='date published')),
|
||||
],
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='choice',
|
||||
name='question',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='polls.Question'),
|
||||
),
|
||||
]
|
0
oldstuff/djtut/mysite/polls/migrations/__init__.py
Normal file
0
oldstuff/djtut/mysite/polls/migrations/__init__.py
Normal file
19
oldstuff/djtut/mysite/polls/models.py
Normal file
19
oldstuff/djtut/mysite/polls/models.py
Normal file
@@ -0,0 +1,19 @@
|
||||
import datetime
|
||||
|
||||
from django.utils import timezone
|
||||
from django.db import models
|
||||
|
||||
|
||||
class Question(models.Model):
|
||||
question_text = models.CharField(max_length=200)
|
||||
pub_date = models.DateTimeField("date published")
|
||||
|
||||
def was_published_recently(self):
|
||||
now = timezone.now()
|
||||
return now - datetime.timedelta(days=1) <= self.pub_date <= now
|
||||
|
||||
|
||||
class Choice(models.Model):
|
||||
question = models.ForeignKey(Question, on_delete=models.CASCADE)
|
||||
choice_text = models.CharField(max_length=200)
|
||||
votes = models.IntegerField(default=0)
|
12
oldstuff/djtut/mysite/polls/templates/polls/detail.html
Normal file
12
oldstuff/djtut/mysite/polls/templates/polls/detail.html
Normal file
@@ -0,0 +1,12 @@
|
||||
<h1>{{ question.question_text }}</h1>
|
||||
|
||||
{% if error_message %}<p><strong>{{ error_mmessage }}</strong></p>{% endif %}
|
||||
|
||||
<form action="{% url "polls:vote" question.id %}" method="post">
|
||||
{% csrf_token %}
|
||||
{% for choice in question.choice_set.all %}
|
||||
<input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}"/>
|
||||
<label for="choice{{ forloop.counter }}">{{ choice.choice_text }}</label><br />
|
||||
{% endfor %}
|
||||
<input type="submit" value="Vote" />
|
||||
</form>
|
9
oldstuff/djtut/mysite/polls/templates/polls/index.html
Normal file
9
oldstuff/djtut/mysite/polls/templates/polls/index.html
Normal file
@@ -0,0 +1,9 @@
|
||||
{% if latest_question_list %}
|
||||
<ul>
|
||||
{% for question in latest_question_list %}
|
||||
<li><a href="{% url "polls:detail" question.id %}">{{ question.question_text }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% else %}
|
||||
<p>No polls are available.</p>
|
||||
{% endif %}
|
9
oldstuff/djtut/mysite/polls/templates/polls/results.html
Normal file
9
oldstuff/djtut/mysite/polls/templates/polls/results.html
Normal file
@@ -0,0 +1,9 @@
|
||||
<h1>{{ question.question_text }}</h1>
|
||||
|
||||
<ul>
|
||||
{% for choice in question.choice_set.all %}
|
||||
<li>{{ choice.choice_text }} -- {{ choice.votes }} vote{{ choice.votes|pluralize }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
<a href="{% url "polls:detail" question.id %}">Vote again?</a>
|
11
oldstuff/djtut/mysite/polls/tests.py
Normal file
11
oldstuff/djtut/mysite/polls/tests.py
Normal file
@@ -0,0 +1,11 @@
|
||||
import datetime
|
||||
|
||||
from django.utils import timezone
|
||||
|
||||
from .models import Question
|
||||
|
||||
|
||||
def test_was_published_recently_with_future_question():
|
||||
time = timezone.now() + datetime.timedelta(days=30)
|
||||
future_question = Question(pub_date=time)
|
||||
assert not future_question.was_published_recently()
|
11
oldstuff/djtut/mysite/polls/urls.py
Normal file
11
oldstuff/djtut/mysite/polls/urls.py
Normal file
@@ -0,0 +1,11 @@
|
||||
from django.conf.urls import url
|
||||
|
||||
from . import views
|
||||
|
||||
app_name = "polls"
|
||||
urlpatterns = [
|
||||
url("^$", views.IndexView.as_view(), name="index"),
|
||||
url("^(?P<pk>[0-9]+)/$", views.DetailView.as_view(), name="detail"),
|
||||
url("^(?P<pk>[0-9]+)/results/$", views.ResultsView.as_view(), name="results",),
|
||||
url("^(?P<question_id>[0-9]+)/vote/$", views.vote, name="vote"),
|
||||
]
|
40
oldstuff/djtut/mysite/polls/views.py
Normal file
40
oldstuff/djtut/mysite/polls/views.py
Normal file
@@ -0,0 +1,40 @@
|
||||
from django.http import HttpResponseRedirect, HttpResponse
|
||||
from django.shortcuts import render, get_object_or_404
|
||||
from django.urls import reverse
|
||||
from django.views import generic
|
||||
|
||||
from .models import Choice, Question
|
||||
|
||||
|
||||
class IndexView(generic.ListView):
|
||||
template_name = "polls/index.html"
|
||||
context_object_name = "latest_question_list"
|
||||
|
||||
def get_queryset(self):
|
||||
return Question.objects.order_by("-pub_date")[:5]
|
||||
|
||||
|
||||
class DetailView(generic.DetailView):
|
||||
model = Question
|
||||
template_name = "polls/detail.html"
|
||||
|
||||
|
||||
class ResultsView(generic.DetailView):
|
||||
model = Question
|
||||
template_name = "polls/results.html"
|
||||
|
||||
|
||||
def vote(request, question_id):
|
||||
question = get_object_or_404(Question, pk=question_id)
|
||||
try:
|
||||
selected_choice = question.choice_set.get(pk=request.POST["choice"])
|
||||
except (KeyError, Choice.DoesNotExist):
|
||||
return render(
|
||||
request,
|
||||
"polls/vote.html",
|
||||
{"question": question, "error_message": "You didn't select a choice."},
|
||||
)
|
||||
else:
|
||||
selected_choice.votes += 1
|
||||
selected_choice.save()
|
||||
return HttpResponseRedirect(reverse("polls:results", args=(question.id,)))
|
2
oldstuff/djtut/mysite/pytest.ini
Normal file
2
oldstuff/djtut/mysite/pytest.ini
Normal file
@@ -0,0 +1,2 @@
|
||||
[pytest]
|
||||
DJANGO_SETTINGS_MODULE = mysite.settings
|
31
oldstuff/farse/cmd/farse-test/main.go
Normal file
31
oldstuff/farse/cmd/farse-test/main.go
Normal file
@@ -0,0 +1,31 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
farse "../.."
|
||||
)
|
||||
|
||||
func main() {
|
||||
fl := farse.New()
|
||||
err := fl.AddKnown(
|
||||
"-a", "-n", "-q", "-m",
|
||||
"--azimuth", "--noodle", "--quince",
|
||||
"whoop", "fizzle", "flim",
|
||||
)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
fmt.Println("known:")
|
||||
for key, tokType := range fl.Known() {
|
||||
fmt.Printf(" %v: %s\n", key, tokType)
|
||||
}
|
||||
|
||||
fmt.Println("scanned:")
|
||||
for _, tok := range fl.Scan(os.Args) {
|
||||
fmt.Printf(" %v: %s\n", tok.Value, tok.Type)
|
||||
}
|
||||
}
|
181
oldstuff/farse/farse.go
Normal file
181
oldstuff/farse/farse.go
Normal file
@@ -0,0 +1,181 @@
|
||||
package farse
|
||||
|
||||
import "fmt"
|
||||
|
||||
type TokenType int
|
||||
|
||||
const (
|
||||
TokenLongFlag TokenType = iota
|
||||
TokenShortFlag
|
||||
TokenShortCompoundFlag
|
||||
TokenIdentifier
|
||||
TokenArgument
|
||||
TokenInvalid
|
||||
TokenSentinel
|
||||
)
|
||||
|
||||
func (t TokenType) String() string {
|
||||
switch t {
|
||||
case TokenLongFlag:
|
||||
return "long flag"
|
||||
case TokenShortFlag:
|
||||
return "short flag"
|
||||
case TokenShortCompoundFlag:
|
||||
return "short compound"
|
||||
case TokenIdentifier:
|
||||
return "identifier"
|
||||
case TokenArgument:
|
||||
return "argument"
|
||||
case TokenInvalid:
|
||||
return "invalid"
|
||||
case TokenSentinel:
|
||||
return "sentinel"
|
||||
}
|
||||
return "(x___x)"
|
||||
}
|
||||
|
||||
type Token struct {
|
||||
Value string
|
||||
Type TokenType
|
||||
}
|
||||
|
||||
type Farse struct {
|
||||
known map[string]TokenType
|
||||
}
|
||||
|
||||
func New() *Farse {
|
||||
return &Farse{
|
||||
known: map[string]TokenType{},
|
||||
}
|
||||
}
|
||||
|
||||
func (fl *Farse) Known() map[string]TokenType {
|
||||
return fl.known
|
||||
}
|
||||
|
||||
func (fl *Farse) AddKnown(knownStrings ...string) error {
|
||||
for i, tok := range scan(knownStrings) {
|
||||
if tok.Type == TokenShortCompoundFlag {
|
||||
return fmt.Errorf("argument %d %q is invalid value for known identifier", i, tok.Value)
|
||||
}
|
||||
|
||||
if len(tok.Value) == 0 {
|
||||
return fmt.Errorf("argument %d is empty", i)
|
||||
}
|
||||
|
||||
if len(tok.Value) == 1 && tok.Value == "-" {
|
||||
return fmt.Errorf("argument %d %q is invalid value for known identifier", i, tok.Value)
|
||||
}
|
||||
|
||||
if _, exists := fl.known[tok.Value]; exists {
|
||||
return fmt.Errorf("argument %d %s conflicts with known", i, tok.Value)
|
||||
}
|
||||
|
||||
fl.known[tok.Value] = tok.Type
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (fl *Farse) Scan(args []string) []*Token {
|
||||
ret := []*Token{}
|
||||
passedSentinel := false
|
||||
|
||||
for _, tok := range scan(args) {
|
||||
if tok.Type == TokenSentinel {
|
||||
ret = append(ret, tok)
|
||||
passedSentinel = true
|
||||
continue
|
||||
}
|
||||
|
||||
if passedSentinel {
|
||||
tok.Type = TokenArgument
|
||||
ret = append(ret, tok)
|
||||
continue
|
||||
}
|
||||
|
||||
if tok.Type == TokenShortCompoundFlag {
|
||||
ret = append(ret, fl.extractCompoundTokens(tok.Value)...)
|
||||
continue
|
||||
}
|
||||
|
||||
if tok.Type == TokenIdentifier {
|
||||
if _, known := fl.known[tok.Value]; !known {
|
||||
tok.Type = TokenArgument
|
||||
}
|
||||
ret = append(ret, tok)
|
||||
}
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func (fl *Farse) extractCompoundTokens(s string) []*Token {
|
||||
ret := []*Token{}
|
||||
|
||||
for j, ch := range s {
|
||||
last := j == (len(s) - 1)
|
||||
|
||||
if j == 0 && ch == '-' {
|
||||
continue
|
||||
}
|
||||
|
||||
sf := string(append([]rune("-"), ch))
|
||||
|
||||
if _, known := fl.known[sf]; known {
|
||||
ret = append(ret, &Token{Value: sf, Type: TokenShortFlag})
|
||||
|
||||
if last {
|
||||
return ret
|
||||
}
|
||||
|
||||
if _, nextKnown := fl.known[string(append([]rune("-"), rune(s[j+1])))]; !nextKnown {
|
||||
ret = append(ret, &Token{Value: s[j+1:], Type: TokenArgument})
|
||||
return ret
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func scan(sl []string) []*Token {
|
||||
ret := []*Token{}
|
||||
|
||||
for _, s := range sl {
|
||||
tok := scanToken(s)
|
||||
if tok != nil {
|
||||
ret = append(ret, tok)
|
||||
}
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func scanToken(s string) *Token {
|
||||
switch len(s) {
|
||||
case 0, 1:
|
||||
return &Token{Value: s, Type: TokenIdentifier}
|
||||
case 2:
|
||||
if s == "--" {
|
||||
return &Token{Value: s, Type: TokenSentinel}
|
||||
}
|
||||
|
||||
if s[0] == '-' {
|
||||
return &Token{Value: s, Type: TokenShortFlag}
|
||||
}
|
||||
default:
|
||||
if s[0] == '-' {
|
||||
if s[1] != '-' {
|
||||
return &Token{Value: s, Type: TokenShortCompoundFlag}
|
||||
}
|
||||
|
||||
return &Token{Value: s, Type: TokenLongFlag}
|
||||
}
|
||||
|
||||
return &Token{Value: s, Type: TokenIdentifier}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
98
oldstuff/graphy/grid.py
Normal file
98
oldstuff/graphy/grid.py
Normal file
@@ -0,0 +1,98 @@
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
|
||||
from trie import Trie
|
||||
|
||||
DEBUG = os.environ.get('DEBUG', '') == '1'
|
||||
|
||||
|
||||
def main():
|
||||
dim = int(os.environ.get('DIM', '3'))
|
||||
words_dat_file = os.environ.get('WORDS_DAT', 'words-en.dat')
|
||||
|
||||
edges = list(map(lambda s: s.strip(), sys.stdin.read().split()))
|
||||
edge_map = {}
|
||||
|
||||
valid_words = Trie.from_dat_file(words_dat_file)
|
||||
|
||||
if len(edges) % dim != 0:
|
||||
raise ValueError('edges length={!r} not divisible by dim={!r}'.format(
|
||||
len(edges), dim))
|
||||
|
||||
for row in range(0, dim):
|
||||
for col in range(0, dim):
|
||||
idx = (row * dim) + col
|
||||
if idx >= len(edges):
|
||||
continue
|
||||
edge_map[(row, col)] = Edge((row, col), edges[idx])
|
||||
|
||||
for (row, col), edge in edge_map.items():
|
||||
for sibling in ((row, col - 1), (row, col + 1), (row - 1, col),
|
||||
(row + 1, col), (row - 1, col - 1), (row - 1, col + 1),
|
||||
(row + 1, col + 1), (row + 1, col - 1)):
|
||||
debug('checking {!r} sibling {!r}'.format((row, col), sibling))
|
||||
if edge_map.get(sibling) is not None:
|
||||
edge.siblings.add(edge_map[sibling])
|
||||
debug(' added sibling {!r} to {!r}'.format(sibling, edge))
|
||||
|
||||
for origin in sorted(edge_map.keys()):
|
||||
for dest in sorted(edge_map.keys()):
|
||||
if origin == dest:
|
||||
continue
|
||||
|
||||
debug('getting paths from origin={!r} to dest={!r}'.format(
|
||||
origin, dest))
|
||||
|
||||
for path in dfs_paths(edge_map, valid_words, origin, dest):
|
||||
print(''.join(list(map(lambda e: edge_map[e].value, path))))
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
class Edge:
|
||||
def __init__(self, id_, value, siblings=None):
|
||||
self.id = id_
|
||||
self.value = value
|
||||
self.siblings = siblings if siblings is not None else set()
|
||||
|
||||
def __repr__(self):
|
||||
return 'Edge({!r}, {!r}, siblings={!r})'.format(
|
||||
self.id, self.value, set(map(lambda s: s.id, self.siblings)))
|
||||
|
||||
@property
|
||||
def sibling_ids(self):
|
||||
return set(map(lambda s: s.id, self.siblings))
|
||||
|
||||
|
||||
def dfs_paths(edge_map, valid_words, origin, dest, path=None):
|
||||
if path is None:
|
||||
debug(' starting new path from {!r}'.format(origin))
|
||||
path = [origin]
|
||||
if origin == dest:
|
||||
debug(' origin={!r} reached dest={!r}, yielding path'.format(
|
||||
origin, dest))
|
||||
if len(path) > 2 and len(path) < 17:
|
||||
yield path
|
||||
|
||||
if ''.join(path) not in valid_words:
|
||||
return
|
||||
|
||||
next_steps = edge_map[origin].sibling_ids - set(path)
|
||||
if not next_steps:
|
||||
return
|
||||
|
||||
debug(' origin={!r} dest={!r} checking next steps in {!r}'.format(
|
||||
origin, dest, next_steps))
|
||||
for next_step in edge_map[origin].sibling_ids - set(path):
|
||||
yield from dfs_paths(edge_map, next_step, dest, path + [next_step])
|
||||
|
||||
|
||||
def debug(msg):
|
||||
if not DEBUG:
|
||||
return
|
||||
print(msg, file=sys.stderr)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
77
oldstuff/graphy/trie.py
Normal file
77
oldstuff/graphy/trie.py
Normal file
@@ -0,0 +1,77 @@
|
||||
import os
|
||||
import pickle
|
||||
import sys
|
||||
|
||||
DEBUG = os.environ.get('DEBUG', '') == '1'
|
||||
|
||||
|
||||
class Trie:
|
||||
def __init__(self, value):
|
||||
self.value = value
|
||||
self.children = []
|
||||
self.is_leaf = False
|
||||
|
||||
def add(self, value):
|
||||
node = self
|
||||
for ch in value:
|
||||
child_matches = False
|
||||
for child in node.children:
|
||||
if child.value == value:
|
||||
node = child
|
||||
child_matches = True
|
||||
break
|
||||
if not child_matches:
|
||||
to_add = Trie(value)
|
||||
node.children.append(to_add)
|
||||
node = to_add
|
||||
node.is_leaf = True
|
||||
|
||||
def __contains__(self, search):
|
||||
node = self
|
||||
if not self.children:
|
||||
return False
|
||||
for ch in search:
|
||||
found = False
|
||||
for child in node.children:
|
||||
if child.value == ch:
|
||||
found = True
|
||||
node = child
|
||||
break
|
||||
if not found:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def main():
|
||||
words_file = os.environ.get('WORDS', 'words-en.txt')
|
||||
words_dat_file = os.environ.get('WORDS_DAT', 'words-en.dat')
|
||||
words_size_range = range(*(
|
||||
map(lambda s: int(s),
|
||||
os.environ.get('WORDS_SIZE_RANGE', '2-15').split('-'))))
|
||||
|
||||
valid_words = Trie('')
|
||||
|
||||
with open(words_file) as inwords:
|
||||
debug('reading from {!r}'.format(words_file))
|
||||
for word in inwords.read().split():
|
||||
if len(word) not in words_size_range:
|
||||
continue
|
||||
|
||||
debug('adding {!r} to valid words'.format(word))
|
||||
valid_words.add(word)
|
||||
|
||||
with open(words_dat_file, 'wb') as outdat:
|
||||
debug('writing valid words to {!r}'.format(words_dat_file))
|
||||
pickle.dump(valid_words, outdat)
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
def debug(msg):
|
||||
if not DEBUG:
|
||||
return
|
||||
print(msg, file=sys.stderr)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
90509
oldstuff/graphy/words-en.txt
Normal file
90509
oldstuff/graphy/words-en.txt
Normal file
File diff suppressed because it is too large
Load Diff
38
oldstuff/kiddofun/quiz.rb
Normal file
38
oldstuff/kiddofun/quiz.rb
Normal file
@@ -0,0 +1,38 @@
|
||||
def main
|
||||
loop do
|
||||
secret_number = rand(0..99)
|
||||
hint_0 = secret_number - rand(0..49)
|
||||
|
||||
loop do
|
||||
say "#{secret_number - hint_0} + #{hint_0} is", newline: false
|
||||
print '?: '
|
||||
begin
|
||||
answer = Integer($stdin.readline.strip)
|
||||
if answer == secret_number
|
||||
say 'You got it!'
|
||||
break
|
||||
else
|
||||
say 'That is so incorrect!'
|
||||
end
|
||||
rescue => e
|
||||
$stderr.puts e
|
||||
say 'NO, Human!'
|
||||
end
|
||||
end
|
||||
|
||||
say 'Do you want to play again? ', newline: false
|
||||
print '[Y/n] '
|
||||
if $stdin.readline.strip.downcase =~ /^n/
|
||||
say 'Goodbye, Human!'
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def say(msg, newline: true)
|
||||
print msg
|
||||
print "\n" if newline
|
||||
system "say -v ralph #{msg.inspect}"
|
||||
end
|
||||
|
||||
main
|
13
oldstuff/kiddofun/rounding.go
Normal file
13
oldstuff/kiddofun/rounding.go
Normal file
@@ -0,0 +1,13 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func main() {
|
||||
number := 43
|
||||
|
||||
fmt.Printf("%-2d - number\n", number)
|
||||
fmt.Printf("%-2d - number tens place\n", number/10)
|
||||
fmt.Printf("%-2d - number tens place multiplied by 10\n", (number/10)*10)
|
||||
}
|
9
oldstuff/kiddofun/rounding.rb
Normal file
9
oldstuff/kiddofun/rounding.rb
Normal file
@@ -0,0 +1,9 @@
|
||||
number = Integer(ARGV.fetch(0))
|
||||
divisor = Float(ARGV.fetch(1, 10.0))
|
||||
|
||||
raise 'Invalid divisor' unless divisor % 10 == 0
|
||||
|
||||
puts "#{number} - number"
|
||||
puts "#{(Float(number) / divisor).round(0)} - number divided by #{divisor}"
|
||||
puts "#{(Float(number) / divisor).round(0) * Integer(divisor)} - " \
|
||||
"number divided by #{divisor}, multiplied by #{Integer(divisor)}"
|
6
oldstuff/lcthw-remnants-2/.gitignore
vendored
Normal file
6
oldstuff/lcthw-remnants-2/.gitignore
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
*.dat
|
||||
ex*
|
||||
!ex29
|
||||
!ex*.c
|
||||
devpkgzed
|
||||
*.log
|
20
oldstuff/lcthw-remnants-2/Dockerfile
Normal file
20
oldstuff/lcthw-remnants-2/Dockerfile
Normal file
@@ -0,0 +1,20 @@
|
||||
FROM ubuntu:xenial
|
||||
|
||||
ENV DEBIAN_FRONTEND noninteractive
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
RUN apt-get update -yq
|
||||
RUN apt-get install -yq --no-install-recommends --no-install-suggests \
|
||||
build-essential \
|
||||
curl \
|
||||
file \
|
||||
gdb \
|
||||
git \
|
||||
man \
|
||||
sudo \
|
||||
vim-tiny \
|
||||
zsh
|
||||
RUN echo "kernel.yama.ptrace_scope = 0" > /etc/sysctl.d/10-ptrace.conf
|
||||
|
||||
CMD ["zsh", "-l"]
|
29
oldstuff/lcthw-remnants-2/Makefile
Normal file
29
oldstuff/lcthw-remnants-2/Makefile
Normal file
@@ -0,0 +1,29 @@
|
||||
SHELL = /bin/bash
|
||||
CFLAGS = -Wall -g -DNDEBUG -fPIC
|
||||
LDLIBS = -ldl
|
||||
|
||||
EXERCISES := $(shell ./list-exercises)
|
||||
|
||||
all: $(EXERCISES)
|
||||
|
||||
ex19: object.o
|
||||
|
||||
ex22_main: ex22.o
|
||||
|
||||
clean:
|
||||
shopt -s nullglob ; \
|
||||
$(RM) $(EXERCISES) *.o *.a
|
||||
|
||||
test:
|
||||
@./runtests
|
||||
|
||||
exercises:
|
||||
@echo $(EXERCISES)
|
||||
|
||||
.PHONY: docker-image
|
||||
docker-image:
|
||||
docker build -t meatballhat/lcthw:latest .
|
||||
|
||||
.PHONY: docker-run
|
||||
docker-run:
|
||||
docker run -it -v $(PWD):/app meatballhat/lcthw
|
3
oldstuff/lcthw-remnants-2/c-skeleton/.gitignore
vendored
Normal file
3
oldstuff/lcthw-remnants-2/c-skeleton/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
tests/runtests
|
||||
tests/*_tests
|
||||
tests/**/*_tests
|
21
oldstuff/lcthw-remnants-2/c-skeleton/LICENSE
Normal file
21
oldstuff/lcthw-remnants-2/c-skeleton/LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
Copyright (C) 2016 Dan Buch
|
||||
|
||||
MIT License
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
59
oldstuff/lcthw-remnants-2/c-skeleton/Makefile
Normal file
59
oldstuff/lcthw-remnants-2/c-skeleton/Makefile
Normal file
@@ -0,0 +1,59 @@
|
||||
CFLAGS = -g -O2 -Wall -Wextra -Isrc -Lbuild -rdynamic -DNDEBUG $(OPTFLAGS)
|
||||
LDLIBS = -ldl $(OPTLIBS)
|
||||
|
||||
PREFIX ?= /usr/local
|
||||
|
||||
SOURCES = $(wildcard src/**/*.c src/*.c)
|
||||
OBJECTS = $(patsubst %.c,%.o,$(SOURCES))
|
||||
|
||||
TEST_SRC = $(wildcard tests/*_tests.c)
|
||||
TESTS = $(patsubst %.c,%,$(TEST_SRC))
|
||||
|
||||
LIBNAME = YOUR_LIBRARY
|
||||
TARGET = build/lib$(LIBNAME).a
|
||||
SO_TARGET = $(patsubst %.a,%.so,$(TARGET))
|
||||
|
||||
# The Target Build
|
||||
all: $(TARGET) $(SO_TARGET) tests
|
||||
|
||||
dev: CFLAGS = -g -Wall -Isrc -Wall -Wextra $(OPTFLAGS)
|
||||
dev: all
|
||||
|
||||
$(TARGET): CFLAGS += -fPIC
|
||||
$(TARGET): build $(OBJECTS)
|
||||
$(AR) rcs $@ $(OBJECTS)
|
||||
ranlib $@
|
||||
|
||||
$(SO_TARGET): $(TARGET) $(OBJECTS)
|
||||
$(CC) -shared -o $@ $(OBJECTS)
|
||||
|
||||
build:
|
||||
@mkdir -p build
|
||||
@mkdir -p bin
|
||||
|
||||
# The Unit Tests
|
||||
.PHONY: tests
|
||||
tests: LDLIBS += -static -l$(LIBNAME)
|
||||
tests: ./tests/runtests $(TESTS)
|
||||
./tests/runtests
|
||||
|
||||
valgrind:
|
||||
VALGRIND="valgrind --log-file=/tmp/valgrind-%p.log" $(MAKE)
|
||||
|
||||
# The Cleaner
|
||||
clean:
|
||||
rm -rf build $(OBJECTS) $(TESTS)
|
||||
rm -f tests/tests.log tests/runtests
|
||||
find . -name "*.gc*" -exec rm {} \;
|
||||
rm -rf `find . -name "*.dSYM" -print`
|
||||
|
||||
# The Install
|
||||
install: all
|
||||
install -d $(DESTDIR)/$(PREFIX)/lib/
|
||||
install $(TARGET) $(DESTDIR)/$(PREFIX)/lib/
|
||||
|
||||
# The Checker
|
||||
BADFUNCS='[^_.>a-zA-Z0-9](str(n?cpy|n?cat|xfrm|n?dup|str|pbrk|tok|_)|stpn?cpy|a?sn?printf|byte_)'
|
||||
check:
|
||||
@echo Files with potentially dangerous functions
|
||||
@egrep $(BADFUNCS) $(SOURCES) || true
|
0
oldstuff/lcthw-remnants-2/c-skeleton/README.md
Normal file
0
oldstuff/lcthw-remnants-2/c-skeleton/README.md
Normal file
30
oldstuff/lcthw-remnants-2/c-skeleton/src/dbg.h
Normal file
30
oldstuff/lcthw-remnants-2/c-skeleton/src/dbg.h
Normal file
@@ -0,0 +1,30 @@
|
||||
#ifndef __dbg_h__
|
||||
#define __dbg_h__
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef NDEBUG
|
||||
#define debug(M, ...)
|
||||
#else
|
||||
#define debug(M, ...) fprintf(stderr, "DEBUG %s:%d:%s: " M "\n", __FILE__, __LINE__, __func__, ##__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#define clean_errno() (errno == 0 ? "None" : strerror(errno))
|
||||
|
||||
#define log_err(M, ...) fprintf(stderr, "[ERROR] (%s:%d:%s: errno: %s) " M "\n", __FILE__, __LINE__, __func__, clean_errno(), ##__VA_ARGS__)
|
||||
|
||||
#define log_warn(M, ...) fprintf(stderr, "[WARN] (%s:%d:%s: errno: %s) " M "\n", __FILE__, __LINE__, __func__, clean_errno(), ##__VA_ARGS__)
|
||||
|
||||
#define log_info(M, ...) fprintf(stderr, "[INFO] (%s:%d:%s) " M "\n", __FILE__, __LINE__, __func__, ##__VA_ARGS__)
|
||||
|
||||
#define check(A, M, ...) if(!(A)) { log_err(M, ##__VA_ARGS__); errno=0; goto error; }
|
||||
|
||||
#define sentinel(M, ...) { log_err(M, ##__VA_ARGS__); errno=0; goto error; }
|
||||
|
||||
#define check_mem(A) check((A), "Out of memory.")
|
||||
|
||||
#define check_debug(A, M, ...) if(!(A)) { debug(M, ##__VA_ARGS__); errno=0; goto error; }
|
||||
|
||||
#endif
|
6
oldstuff/lcthw-remnants-2/c-skeleton/src/your_library.c
Normal file
6
oldstuff/lcthw-remnants-2/c-skeleton/src/your_library.c
Normal file
@@ -0,0 +1,6 @@
|
||||
#include "your_library.h"
|
||||
|
||||
int howmanyweasels()
|
||||
{
|
||||
return WEASELS;
|
||||
}
|
8
oldstuff/lcthw-remnants-2/c-skeleton/src/your_library.h
Normal file
8
oldstuff/lcthw-remnants-2/c-skeleton/src/your_library.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#ifndef _your_library_h
|
||||
#define _your_library_h
|
||||
|
||||
#define WEASELS 23
|
||||
|
||||
int howmanyweasels();
|
||||
|
||||
#endif
|
38
oldstuff/lcthw-remnants-2/c-skeleton/tests/minunit.h
Normal file
38
oldstuff/lcthw-remnants-2/c-skeleton/tests/minunit.h
Normal file
@@ -0,0 +1,38 @@
|
||||
#undef DNDEBUG
|
||||
#ifndef _minunit_h
|
||||
#define _minunit_h
|
||||
|
||||
#include <stdio.h>
|
||||
#include <dbg.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define mu_suite_start() char *message = NULL
|
||||
|
||||
#define mu_assert(test, message) if (!(test)) {\
|
||||
log_err(message); return message;\
|
||||
}\
|
||||
assertions_made++;
|
||||
#define mu_run_test(test) debug("\n-----%s", " " #test); \
|
||||
message = test(); tests_run++; if (message) return message;
|
||||
|
||||
#define RUN_TESTS(name) int main(int argc, char *argv[]) {\
|
||||
argc = argc; \
|
||||
argv = argv; \
|
||||
debug("----- RUNNING: %s", argv[0]);\
|
||||
printf("----\nRUNNING: %s\n", argv[0]);\
|
||||
char *result = name();\
|
||||
if (result != 0) {\
|
||||
printf("FAILED: %s\n", result);\
|
||||
}\
|
||||
else {\
|
||||
printf("ALL TESTS PASSED\n");\
|
||||
}\
|
||||
printf("Tests run: %d\n", tests_run);\
|
||||
printf("Assertions made: %d\n", assertions_made);\
|
||||
exit(result != 0);\
|
||||
}
|
||||
|
||||
int tests_run;
|
||||
int assertions_made;
|
||||
|
||||
#endif
|
107
oldstuff/lcthw-remnants-2/c-skeleton/tests/runtests.c
Normal file
107
oldstuff/lcthw-remnants-2/c-skeleton/tests/runtests.c
Normal file
@@ -0,0 +1,107 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
#include <unistd.h>
|
||||
#include <fnmatch.h>
|
||||
#include <dbg.h>
|
||||
|
||||
int test_selector(const struct dirent *ep)
|
||||
{
|
||||
return fnmatch("*_tests", ep->d_name, 0) == 0;
|
||||
}
|
||||
|
||||
int run_tests_file(char *filename)
|
||||
{
|
||||
if(access(filename, R_OK | X_OK) == 0) {
|
||||
return system(filename);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int entcount = 0;
|
||||
int rc = 0;
|
||||
int i = 0;
|
||||
int ntests = 0;
|
||||
char *testsdir = NULL;
|
||||
char *valgrind = getenv("VALGRIND");
|
||||
struct dirent **namelist = NULL;
|
||||
struct dirent *ep = NULL;
|
||||
|
||||
if(argc > 1) {
|
||||
testsdir = argv[1];
|
||||
}
|
||||
|
||||
if(!testsdir) {
|
||||
testsdir = getenv("TESTS");
|
||||
}
|
||||
|
||||
if(!testsdir) {
|
||||
testsdir = "./tests";
|
||||
}
|
||||
|
||||
entcount = scandir((const char *)testsdir, &namelist, test_selector, alphasort);
|
||||
check(entcount > -1, "Failed to scan tests dir");
|
||||
|
||||
for(i = 0; i < entcount; i++) {
|
||||
ep = namelist[i];
|
||||
check(ep, "Dirent is missing.");
|
||||
|
||||
char filename[256];
|
||||
rc = sprintf(filename, "%s/%s", testsdir, ep->d_name);
|
||||
check(rc > -1, "Failed to build filename.");
|
||||
debug("Found filename '%s'", filename);
|
||||
|
||||
free(ep);
|
||||
|
||||
if(valgrind) {
|
||||
char command[1024];
|
||||
rc = sprintf(command, "%s %s", valgrind, filename);
|
||||
check(rc > -1, "Failed to build command with valgrind.");
|
||||
rc = run_tests_file(command);
|
||||
} else {
|
||||
rc = run_tests_file(filename);
|
||||
}
|
||||
|
||||
if(rc > 0) {
|
||||
debug("Skipping '%s'", filename);
|
||||
continue;
|
||||
}
|
||||
|
||||
ntests++;
|
||||
|
||||
if(rc == 0) {
|
||||
printf("%s PASS\n", filename);
|
||||
continue;
|
||||
}
|
||||
|
||||
printf("ERROR in test %s", filename);
|
||||
if(access("tests/tests.log", R_OK) == 0) {
|
||||
printf(": here's tests/tests.log\n");
|
||||
printf("------\n");
|
||||
rc = system("tail tests/tests.log");
|
||||
} else {
|
||||
printf("\n");
|
||||
}
|
||||
goto error;
|
||||
}
|
||||
|
||||
printf("------\n");
|
||||
printf("Total of %d test file%s run.\n", ntests, ntests > 1 ? "s" : "");
|
||||
|
||||
if(namelist) {
|
||||
free(namelist);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
if(namelist) {
|
||||
free(namelist);
|
||||
}
|
||||
|
||||
return rc != 0 ? rc : 1;
|
||||
}
|
@@ -0,0 +1,8 @@
|
||||
#include <stdio.h>
|
||||
#include "your_library.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
printf("WEASELS: %d\n", howmanyweasels());
|
||||
return 0;
|
||||
}
|
30
oldstuff/lcthw-remnants-2/dbg.h
Normal file
30
oldstuff/lcthw-remnants-2/dbg.h
Normal file
@@ -0,0 +1,30 @@
|
||||
#ifndef __dbg_h__
|
||||
#define __dbg_h__
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef NDEBUG
|
||||
#define debug(M, ...)
|
||||
#else
|
||||
#define debug(M, ...) fprintf(stderr, "DEBUG %s:%d:%s: " M "\n", __FILE__, __LINE__, __func__, ##__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#define clean_errno() (errno == 0 ? "None" : strerror(errno))
|
||||
|
||||
#define log_err(M, ...) fprintf(stderr, "[ERROR] (%s:%d:%s: errno: %s) " M "\n", __FILE__, __LINE__, __func__, clean_errno(), ##__VA_ARGS__)
|
||||
|
||||
#define log_warn(M, ...) fprintf(stderr, "[WARN] (%s:%d:%s: errno: %s) " M "\n", __FILE__, __LINE__, __func__, clean_errno(), ##__VA_ARGS__)
|
||||
|
||||
#define log_info(M, ...) fprintf(stderr, "[INFO] (%s:%d:%s) " M "\n", __FILE__, __LINE__, __func__, ##__VA_ARGS__)
|
||||
|
||||
#define check(A, M, ...) if(!(A)) { log_err(M, ##__VA_ARGS__); errno=0; goto error; }
|
||||
|
||||
#define sentinel(M, ...) { log_err(M, ##__VA_ARGS__); errno=0; goto error; }
|
||||
|
||||
#define check_mem(A) check((A), "Out of memory.")
|
||||
|
||||
#define check_debug(A, M, ...) if(!(A)) { debug(M, ##__VA_ARGS__); errno=0; goto error; }
|
||||
|
||||
#endif
|
2
oldstuff/lcthw-remnants-2/devpkg/.gitignore
vendored
Normal file
2
oldstuff/lcthw-remnants-2/devpkg/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
bstrlib.*
|
||||
devpkg
|
30
oldstuff/lcthw-remnants-2/devpkg/Makefile
Normal file
30
oldstuff/lcthw-remnants-2/devpkg/Makefile
Normal file
@@ -0,0 +1,30 @@
|
||||
BSTRLIB_BASE_URL ?= https://raw.githubusercontent.com/websnarf/bstrlib/208b1f2a4dfc96b806ed499bd1909e87ec15981d
|
||||
PREFIX ?= /usr/local
|
||||
CFLAGS = -g -Wall -I${PREFIX}/apr/include/apr-1 -I${PREFIX}/apr/include/apr-util-1
|
||||
LDFLAGS = -L${PREFIX}/apr/lib
|
||||
LDLIBS = -lapr-1 -pthread -laprutil-1
|
||||
|
||||
all: devpkg
|
||||
|
||||
devpkg: bstrlib.o db.o shell.o commands.o
|
||||
|
||||
prebuild:
|
||||
sudo mkdir -p /etc/ld.so.conf.d
|
||||
echo $(DESTDIR)/$(PREFIX)/lib | sudo tee /etc/ld.so.conf.d/devpkg.conf
|
||||
sudo ldconfig
|
||||
|
||||
install: all
|
||||
install -d $(DESTDIR)/$(PREFIX)/bin/
|
||||
install devpkg $(DESTDIR)/$(PREFIX)/bin/
|
||||
|
||||
clean:
|
||||
$(RM) *.o
|
||||
$(RM) devpkg
|
||||
$(RM) *.dSYM
|
||||
$(RM) bstrlib.c bstrlib.h
|
||||
|
||||
bstrlib.c: bstrlib.h
|
||||
curl -sSLO $(BSTRLIB_BASE_URL)/bstrlib.c
|
||||
|
||||
bstrlib.h:
|
||||
curl -sSLO $(BSTRLIB_BASE_URL)/bstrlib.h
|
47
oldstuff/lcthw-remnants-2/devpkg/README
Normal file
47
oldstuff/lcthw-remnants-2/devpkg/README
Normal file
@@ -0,0 +1,47 @@
|
||||
# `devpkg`
|
||||
|
||||
This is a thingy that downloads, builds, and installs stuff!
|
||||
|
||||
## usage
|
||||
|
||||
Before you can do the fun part, you need to initialize the bits:
|
||||
|
||||
``` bash
|
||||
devpkg -S
|
||||
```
|
||||
|
||||
Install something via URL:
|
||||
|
||||
``` bash
|
||||
devpkg -I http://example.org/foo.tar.bz2
|
||||
```
|
||||
|
||||
Install something via URL with custom arguments for configure, make, and
|
||||
install:
|
||||
|
||||
``` bash
|
||||
devpkg -I http://example.org/foo.tar.bz2 -c '--no-flair' -m 'CFLAGS+=-Wall' -i '-n'
|
||||
```
|
||||
|
||||
Perform a fetch *only* without building or installing:
|
||||
|
||||
``` bash
|
||||
devpkg -F http://example.org/foo.tar.bz2
|
||||
```
|
||||
|
||||
Perform a build *only* without installing:
|
||||
|
||||
``` bash
|
||||
devpkg -B http://example.org/foo.tar.bz2
|
||||
```
|
||||
|
||||
List the stuff that's been installed:
|
||||
|
||||
``` bash
|
||||
devpkg -L
|
||||
```
|
||||
|
||||
|
||||
<!--
|
||||
vim:filetype=markdown
|
||||
-->
|
174
oldstuff/lcthw-remnants-2/devpkg/commands.c
Normal file
174
oldstuff/lcthw-remnants-2/devpkg/commands.c
Normal file
@@ -0,0 +1,174 @@
|
||||
#include <apr_uri.h>
|
||||
#include <apr_fnmatch.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "commands.h"
|
||||
#include "dbg.h"
|
||||
#include "bstrlib.h"
|
||||
#include "db.h"
|
||||
#include "shell.h"
|
||||
|
||||
|
||||
int Command_depends(apr_pool_t *p, const char *path)
|
||||
{
|
||||
FILE *in = NULL;
|
||||
bstring line = NULL;
|
||||
|
||||
in = fopen(path, "r");
|
||||
check(in != NULL, "Failed to open downloaded depends: %s", path);
|
||||
|
||||
for(line = bgets((bNgetc)fgetc, in, '\n'); line != NULL;
|
||||
line = bgets((bNgetc)fgetc, in, '\n'))
|
||||
{
|
||||
btrimws(line);
|
||||
log_info("Processing depends: %s", bdata(line));
|
||||
int rc = Command_install(p, bdata(line), NULL, NULL, NULL);
|
||||
check(rc == 0, "Failed to install: %s", bdata(line));
|
||||
bdestroy(line);
|
||||
}
|
||||
|
||||
fclose(in);
|
||||
return 0;
|
||||
|
||||
error:
|
||||
if(line) bdestroy(line);
|
||||
if(in) fclose(in);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int Command_fetch(apr_pool_t *p, const char *url, int fetch_only)
|
||||
{
|
||||
apr_uri_t info = {.port = 0};
|
||||
int rc = 0;
|
||||
const char *depends_file = NULL;
|
||||
apr_status_t rv = apr_uri_parse(p, url, &info);
|
||||
|
||||
check(rv == APR_SUCCESS, "Failed to parse URL: %s", url);
|
||||
|
||||
if(apr_fnmatch(GIT_PAT, info.path, 0) == APR_SUCCESS) {
|
||||
rc = Shell_exec(GIT_SH, "URL", url, NULL);
|
||||
check(rc == 0, "git failed.");
|
||||
} else if(apr_fnmatch(DEPEND_PAT, info.path, 0) == APR_SUCCESS) {
|
||||
check(!fetch_only, "No point in fetching a DEPENDS file.");
|
||||
|
||||
if(info.scheme) {
|
||||
depends_file = DEPENDS_PATH;
|
||||
rc = Shell_exec(CURL_SH, "URL", url, "TARGET", depends_file, NULL);
|
||||
check(rc == 0, "Curl failed.");
|
||||
} else {
|
||||
depends_file = info.path;
|
||||
}
|
||||
|
||||
// recursively process the devpkg list
|
||||
log_info("Building according to DEPENDS: %s", url);
|
||||
rv = Command_depends(p, depends_file);
|
||||
check(rv == 0, "Failed to process the DEPENDS: %s", url);
|
||||
|
||||
// this indicates that nothing needs to be done
|
||||
return 0;
|
||||
|
||||
} else if(apr_fnmatch(TAR_GZ_PAT, info.path, 0) == APR_SUCCESS) {
|
||||
if(info.scheme) {
|
||||
rc = Shell_exec(CURL_SH,
|
||||
"URL", url,
|
||||
"TARGET", TAR_GZ_SRC, NULL);
|
||||
check(rc == 0, "Failed to curl source: %s", url);
|
||||
}
|
||||
|
||||
rv = apr_dir_make_recursive(BUILD_DIR,
|
||||
APR_UREAD | APR_UWRITE | APR_UEXECUTE, p);
|
||||
check(rv == APR_SUCCESS, "Failed to make directory %s", BUILD_DIR);
|
||||
|
||||
rc = Shell_exec(TAR_SH, "FILE", TAR_GZ_SRC, NULL);
|
||||
check(rc == 0, "Failed to untar %s", TAR_GZ_SRC);
|
||||
} else if(apr_fnmatch(TAR_BZ2_PAT, info.path, 0) == APR_SUCCESS) {
|
||||
if(info.scheme) {
|
||||
rc = Shell_exec(CURL_SH, "URL", url, "TARGET", TAR_BZ2_SRC, NULL);
|
||||
check(rc == 0, "Curl failed.");
|
||||
}
|
||||
|
||||
apr_status_t rc = apr_dir_make_recursive(BUILD_DIR,
|
||||
APR_UREAD | APR_UWRITE | APR_UEXECUTE, p);
|
||||
|
||||
check(rc == 0, "Failed to make directory %s", BUILD_DIR);
|
||||
rc = Shell_exec(TAR_SH, "FILE", TAR_BZ2_SRC, NULL);
|
||||
check(rc == 0, "Failed to untar %s", TAR_BZ2_SRC);
|
||||
} else {
|
||||
sentinel("Don't know how to handle %s", url);
|
||||
}
|
||||
|
||||
// indicates that an install needs to actually run
|
||||
return 1;
|
||||
error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
int Command_build(apr_pool_t *p, const char *url, const char *configure_opts,
|
||||
const char *make_opts, const char *install_opts)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
check(access(BUILD_DIR, X_OK | R_OK | W_OK) == 0,
|
||||
"Build directory doesn't exist: %s", BUILD_DIR);
|
||||
|
||||
// actually do an install
|
||||
if(access(CONFIG_SCRIPT, X_OK) == 0) {
|
||||
log_info("Has a configure script, running it.");
|
||||
rc = Shell_exec(CONFIGURE_SH, "OPTS", configure_opts, NULL);
|
||||
check(rc == 0, "Failed to configure");
|
||||
}
|
||||
|
||||
rc = Shell_exec(MAKE_SH, "OPTS", make_opts, NULL);
|
||||
check(rc == 0, "Failed to build.");
|
||||
|
||||
rc = Shell_exec(INSTALL_SH,
|
||||
"TARGET", install_opts ? install_opts : "install",
|
||||
NULL);
|
||||
check(rc == 0, "Failed to install.");
|
||||
|
||||
rc = Shell_exec(CLEANUP_SH, NULL);
|
||||
check(rc == 0, "Failed to cleanup after build.");
|
||||
|
||||
rc = DB_update(url);
|
||||
check(rc == 0, "Failed to add this package to the database.");
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
int Command_install(apr_pool_t *p, const char *url, const char *configure_opts,
|
||||
const char *make_opts, const char *install_opts)
|
||||
{
|
||||
int rc = 0;
|
||||
check(Shell_exec(CLEANUP_SH, NULL) == 0, "Failed to cleanup before building.");
|
||||
|
||||
rc = DB_find(url);
|
||||
check(rc != -1, "Error checking the install database.");
|
||||
|
||||
if(rc == 1) {
|
||||
log_info("Package %s already installed.", url);
|
||||
return 0;
|
||||
}
|
||||
|
||||
rc = Command_fetch(p, url, 0);
|
||||
|
||||
if(rc == 1) {
|
||||
rc = Command_build(p, url, configure_opts, make_opts, install_opts);
|
||||
check(rc == 0, "Failed to build: %s", url);
|
||||
} else if(rc == 0) {
|
||||
// no install needed
|
||||
log_info("Depends successfully installed: %s", url);
|
||||
} else {
|
||||
// had an error
|
||||
sentinel("Install failed: %s", url);
|
||||
}
|
||||
|
||||
Shell_exec(CLEANUP_SH, NULL);
|
||||
return 0;
|
||||
|
||||
error:
|
||||
Shell_exec(CLEANUP_SH, NULL);
|
||||
return -1;
|
||||
}
|
31
oldstuff/lcthw-remnants-2/devpkg/commands.h
Normal file
31
oldstuff/lcthw-remnants-2/devpkg/commands.h
Normal file
@@ -0,0 +1,31 @@
|
||||
#ifndef _commands_h
|
||||
#define _commands_h
|
||||
|
||||
#include <apr_pools.h>
|
||||
|
||||
#define DEPENDS_PATH "/tmp/DEPENDS"
|
||||
#define TAR_GZ_SRC "/tmp/pkg-src.tar.gz"
|
||||
#define TAR_BZ2_SRC "/tmp/pkg-src.tar.bz2"
|
||||
#define BUILD_DIR "/tmp/pkg-build"
|
||||
#define GIT_PAT "*.git"
|
||||
#define DEPEND_PAT "*DEPENDS"
|
||||
#define TAR_GZ_PAT "*.tar.gz"
|
||||
#define TAR_BZ2_PAT "*.tar.bz2"
|
||||
#define CONFIG_SCRIPT "/tmp/pkg-build/configure"
|
||||
|
||||
enum CommandType {
|
||||
COMMAND_NONE, COMMAND_INSTALL, COMMAND_LIST, COMMAND_FETCH,
|
||||
COMMAND_INIT, COMMAND_BUILD
|
||||
};
|
||||
|
||||
int Command_fetch(apr_pool_t *p, const char *url, int fetch_only);
|
||||
|
||||
int Command_install(apr_pool_t *p, const char *url, const char *configure_opts,
|
||||
const char *make_opts, const char *install_opts);
|
||||
|
||||
int Command_depends(apr_pool_t *p, const char *path);
|
||||
|
||||
int Command_build(apr_pool_t *p, const char *url, const char *configure_opts,
|
||||
const char *make_opts, const char *install_opts);
|
||||
|
||||
#endif
|
125
oldstuff/lcthw-remnants-2/devpkg/db.c
Normal file
125
oldstuff/lcthw-remnants-2/devpkg/db.c
Normal file
@@ -0,0 +1,125 @@
|
||||
#include <unistd.h>
|
||||
#include <apr_errno.h>
|
||||
#include <apr_file_io.h>
|
||||
|
||||
#include "db.h"
|
||||
#include "bstrlib.h"
|
||||
#include "dbg.h"
|
||||
|
||||
static FILE *DB_open(const char *path, const char *mode)
|
||||
{
|
||||
return fopen(path, mode);
|
||||
}
|
||||
|
||||
|
||||
static void DB_close(FILE *db)
|
||||
{
|
||||
fclose(db);
|
||||
}
|
||||
|
||||
|
||||
static bstring DB_load()
|
||||
{
|
||||
FILE *db = NULL;
|
||||
bstring data = NULL;
|
||||
|
||||
db = DB_open(DB_FILE, "r");
|
||||
check(db, "Failed to open database: %s", DB_FILE);
|
||||
|
||||
data = bread((bNread)fread, db);
|
||||
check(data, "Failed to read from db file: %s", DB_FILE);
|
||||
|
||||
DB_close(db);
|
||||
return data;
|
||||
|
||||
error:
|
||||
if(db) DB_close(db);
|
||||
if(data) bdestroy(data);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
int DB_update(const char *url)
|
||||
{
|
||||
if(DB_find(url)) {
|
||||
log_info("Already recorded as installed: %s", url);
|
||||
}
|
||||
|
||||
FILE *db = DB_open(DB_FILE, "a+");
|
||||
check(db, "Failed to open DB file: %s", DB_FILE);
|
||||
|
||||
bstring line = bfromcstr(url);
|
||||
bconchar(line, '\n');
|
||||
int rc = fwrite(line->data, blength(line), 1, db);
|
||||
check(rc == 1, "Failed to append to the db.");
|
||||
|
||||
return 0;
|
||||
error:
|
||||
if(db) DB_close(db);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int DB_find(const char *url)
|
||||
{
|
||||
bstring data = NULL;
|
||||
bstring line = bfromcstr(url);
|
||||
int res = -1;
|
||||
|
||||
data = DB_load();
|
||||
check(data, "Failed to load: %s", DB_FILE);
|
||||
|
||||
if(binstr(data, 0, line) == BSTR_ERR) {
|
||||
res = 0;
|
||||
} else {
|
||||
res = 1;
|
||||
}
|
||||
|
||||
error: // fallthrough
|
||||
if(data) bdestroy(data);
|
||||
if(line) bdestroy(line);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
int DB_init()
|
||||
{
|
||||
apr_pool_t *p = NULL;
|
||||
apr_pool_initialize();
|
||||
apr_pool_create(&p, NULL);
|
||||
|
||||
if(access(DB_DIR, W_OK | X_OK) == -1) {
|
||||
apr_status_t rc = apr_dir_make_recursive(DB_DIR,
|
||||
APR_UREAD | APR_UWRITE | APR_UEXECUTE |
|
||||
APR_GREAD | APR_GWRITE | APR_GEXECUTE, p);
|
||||
check(rc == APR_SUCCESS, "Failed to make database dir: %s", DB_DIR);
|
||||
}
|
||||
|
||||
if(access(DB_FILE, W_OK) == -1) {
|
||||
FILE *db = DB_open(DB_FILE, "w");
|
||||
check(db, "Cannot open database: %s", DB_FILE);
|
||||
DB_close(db);
|
||||
}
|
||||
|
||||
apr_pool_destroy(p);
|
||||
return 0;
|
||||
|
||||
error:
|
||||
apr_pool_destroy(p);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int DB_list()
|
||||
{
|
||||
bstring data = DB_load();
|
||||
check(data, "Failed to read load: %s", DB_FILE);
|
||||
|
||||
printf("%s", bdata(data));
|
||||
bdestroy(data);
|
||||
return 0;
|
||||
|
||||
error:
|
||||
return -1;
|
||||
}
|
12
oldstuff/lcthw-remnants-2/devpkg/db.h
Normal file
12
oldstuff/lcthw-remnants-2/devpkg/db.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#ifndef _db_h
|
||||
#define _db_h
|
||||
|
||||
#define DB_FILE "/usr/local/.devpkg/db"
|
||||
#define DB_DIR "/usr/local/.devpkg"
|
||||
|
||||
int DB_init();
|
||||
int DB_list();
|
||||
int DB_update(const char *url);
|
||||
int DB_find(const char *url);
|
||||
|
||||
#endif
|
30
oldstuff/lcthw-remnants-2/devpkg/dbg.h
Normal file
30
oldstuff/lcthw-remnants-2/devpkg/dbg.h
Normal file
@@ -0,0 +1,30 @@
|
||||
#ifndef __dbg_h__
|
||||
#define __dbg_h__
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef NDEBUG
|
||||
#define debug(M, ...)
|
||||
#else
|
||||
#define debug(M, ...) fprintf(stderr, "DEBUG %s:%d:%s: " M "\n", __FILE__, __LINE__, __func__, ##__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#define clean_errno() (errno == 0 ? "None" : strerror(errno))
|
||||
|
||||
#define log_err(M, ...) fprintf(stderr, "[ERROR] (%s:%d:%s: errno: %s) " M "\n", __FILE__, __LINE__, __func__, clean_errno(), ##__VA_ARGS__)
|
||||
|
||||
#define log_warn(M, ...) fprintf(stderr, "[WARN] (%s:%d:%s: errno: %s) " M "\n", __FILE__, __LINE__, __func__, clean_errno(), ##__VA_ARGS__)
|
||||
|
||||
#define log_info(M, ...) fprintf(stderr, "[INFO] (%s:%d:%s) " M "\n", __FILE__, __LINE__, __func__, ##__VA_ARGS__)
|
||||
|
||||
#define check(A, M, ...) if(!(A)) { log_err(M, ##__VA_ARGS__); errno=0; goto error; }
|
||||
|
||||
#define sentinel(M, ...) { log_err(M, ##__VA_ARGS__); errno=0; goto error; }
|
||||
|
||||
#define check_mem(A) check((A), "Out of memory.")
|
||||
|
||||
#define check_debug(A, M, ...) if(!(A)) { debug(M, ##__VA_ARGS__); errno=0; goto error; }
|
||||
|
||||
#endif
|
104
oldstuff/lcthw-remnants-2/devpkg/devpkg.c
Normal file
104
oldstuff/lcthw-remnants-2/devpkg/devpkg.c
Normal file
@@ -0,0 +1,104 @@
|
||||
#include <stdio.h>
|
||||
#include <apr_general.h>
|
||||
#include <apr_getopt.h>
|
||||
#include <apr_strings.h>
|
||||
#include <apr_lib.h>
|
||||
|
||||
#include "dbg.h"
|
||||
#include "db.h"
|
||||
#include "commands.h"
|
||||
|
||||
int main(int argc, const char const *argv[])
|
||||
{
|
||||
apr_pool_t *p = NULL;
|
||||
apr_pool_initialize();
|
||||
apr_pool_create(&p, NULL);
|
||||
|
||||
apr_getopt_t *opt;
|
||||
apr_status_t rv;
|
||||
|
||||
char ch = '\0';
|
||||
const char *optarg = NULL;
|
||||
const char *config_opts = NULL;
|
||||
const char *install_opts = NULL;
|
||||
const char *make_opts = NULL;
|
||||
const char *url = NULL;
|
||||
enum CommandType request = COMMAND_NONE;
|
||||
|
||||
|
||||
rv = apr_getopt_init(&opt, p, argc, argv);
|
||||
|
||||
while(apr_getopt(opt, "I:Lc:m:i:d:SF:B:", &ch, &optarg) == APR_SUCCESS) {
|
||||
switch(ch) {
|
||||
case 'I':
|
||||
request = COMMAND_INSTALL;
|
||||
url = optarg;
|
||||
break;
|
||||
|
||||
case 'L':
|
||||
request = COMMAND_LIST;
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
config_opts = optarg;
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
make_opts = optarg;
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
install_opts = optarg;
|
||||
break;
|
||||
|
||||
case 'S':
|
||||
request = COMMAND_INIT;
|
||||
break;
|
||||
|
||||
case 'F':
|
||||
request = COMMAND_FETCH;
|
||||
url = optarg;
|
||||
break;
|
||||
|
||||
case 'B':
|
||||
request = COMMAND_BUILD;
|
||||
url = optarg;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch(request) {
|
||||
case COMMAND_INSTALL:
|
||||
check(url, "You must at least give a URL.");
|
||||
Command_install(p, url, config_opts, make_opts, install_opts);
|
||||
break;
|
||||
|
||||
case COMMAND_LIST:
|
||||
DB_list();
|
||||
break;
|
||||
|
||||
case COMMAND_FETCH:
|
||||
check(url != NULL, "You must give a URL.");
|
||||
Command_fetch(p, url, 1);
|
||||
log_info("Downloaded to %s and in /tmp/", BUILD_DIR);
|
||||
break;
|
||||
|
||||
case COMMAND_BUILD:
|
||||
check(url, "You must at least give a URL.");
|
||||
Command_build(p, url, config_opts, make_opts, install_opts);
|
||||
break;
|
||||
|
||||
case COMMAND_INIT:
|
||||
rv = DB_init();
|
||||
check(rv == 0, "Failed to make the database.");
|
||||
break;
|
||||
|
||||
default:
|
||||
sentinel("Invalid command given.");
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
return 1;
|
||||
}
|
120
oldstuff/lcthw-remnants-2/devpkg/shell.c
Normal file
120
oldstuff/lcthw-remnants-2/devpkg/shell.c
Normal file
@@ -0,0 +1,120 @@
|
||||
#include "shell.h"
|
||||
#include "dbg.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
int Shell_exec(Shell template, ...)
|
||||
{
|
||||
apr_pool_t *p = NULL;
|
||||
int rc = -1;
|
||||
apr_status_t rv = APR_SUCCESS;
|
||||
va_list argp;
|
||||
const char *key = NULL;
|
||||
const char *arg = NULL;
|
||||
int i = 0;
|
||||
|
||||
rv = apr_pool_create(&p, NULL);
|
||||
check(rv == APR_SUCCESS, "Failed to create pool.");
|
||||
|
||||
va_start(argp, template);
|
||||
|
||||
for(key = va_arg(argp, const char *);
|
||||
key != NULL;
|
||||
key = va_arg(argp, const char *))
|
||||
{
|
||||
arg = va_arg(argp, const char *);
|
||||
|
||||
for(i = 0; template.args[i] != NULL; i++) {
|
||||
if(strcmp(template.args[i], key) == 0) {
|
||||
template.args[i] = arg;
|
||||
break; // found it
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rc = Shell_run(p, &template);
|
||||
apr_pool_destroy(p);
|
||||
va_end(argp);
|
||||
return rc;
|
||||
|
||||
error:
|
||||
if(p) {
|
||||
apr_pool_destroy(p);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
int Shell_run(apr_pool_t *p, Shell *cmd)
|
||||
{
|
||||
apr_procattr_t *attr;
|
||||
apr_status_t rv;
|
||||
apr_proc_t newproc;
|
||||
|
||||
rv = apr_procattr_create(&attr, p);
|
||||
check(rv == APR_SUCCESS, "Failed to create proc attr.");
|
||||
|
||||
rv = apr_procattr_io_set(attr, APR_NO_PIPE, APR_NO_PIPE, APR_NO_PIPE);
|
||||
check(rv == APR_SUCCESS, "Failed to set IO of command.");
|
||||
|
||||
rv = apr_procattr_dir_set(attr, cmd->dir);
|
||||
check(rv == APR_SUCCESS, "Failed to set root to %s", cmd->dir);
|
||||
|
||||
rv = apr_procattr_cmdtype_set(attr, APR_PROGRAM_PATH);
|
||||
check(rv == APR_SUCCESS, "Failed to set cmd type.");
|
||||
|
||||
rv = apr_proc_create(&newproc, cmd->exe, cmd->args, NULL, attr, p);
|
||||
check(rv == APR_SUCCESS, "Failed to run command.");
|
||||
|
||||
rv = apr_proc_wait(&newproc, &cmd->exit_code, &cmd->exit_why, APR_WAIT);
|
||||
check(rv == APR_CHILD_DONE, "Failed to wait.");
|
||||
|
||||
check(cmd->exit_code == 0, "%s exited badly.", cmd->exe);
|
||||
check(cmd->exit_why == APR_PROC_EXIT, "%s was killed or crashed", cmd->exe);
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
Shell CLEANUP_SH = {
|
||||
.exe = "rm",
|
||||
.dir = "/tmp",
|
||||
.args = {"rm", "-rf", "/tmp/pkg-build", "/tmp/pkg-src.tar.gz",
|
||||
"/tmp/pkg-src.tar.bz2", "/tmp/DEPENDS", NULL}
|
||||
};
|
||||
|
||||
Shell GIT_SH = {
|
||||
.dir = "/tmp",
|
||||
.exe = "git",
|
||||
.args = {"git", "clone", "URL", "pkg-build", NULL}
|
||||
};
|
||||
|
||||
Shell TAR_SH = {
|
||||
.dir = "/tmp/pkg-build",
|
||||
.exe = "tar",
|
||||
.args = {"tar", "-xzf", "FILE", "--strip-components", "1", NULL}
|
||||
};
|
||||
|
||||
Shell CURL_SH = {
|
||||
.dir = "/tmp",
|
||||
.exe = "curl",
|
||||
.args = {"curl", "-L", "-o", "TARGET", "URL", NULL}
|
||||
};
|
||||
|
||||
Shell CONFIGURE_SH = {
|
||||
.exe = "./configure",
|
||||
.dir = "/tmp/pkg-build",
|
||||
.args = {"configure", "OPTS", NULL},
|
||||
};
|
||||
|
||||
Shell MAKE_SH = {
|
||||
.exe = "make",
|
||||
.dir = "/tmp/pkg-build",
|
||||
.args = {"make", "OPTS", NULL}
|
||||
};
|
||||
|
||||
Shell INSTALL_SH = {
|
||||
.exe = "sudo",
|
||||
.dir = "/tmp/pkg-build",
|
||||
.args = {"sudo", "make", "TARGET", NULL}
|
||||
};
|
31
oldstuff/lcthw-remnants-2/devpkg/shell.h
Normal file
31
oldstuff/lcthw-remnants-2/devpkg/shell.h
Normal file
@@ -0,0 +1,31 @@
|
||||
#ifndef _shell_h
|
||||
#define _shell_h
|
||||
|
||||
#define MAX_COMMAND_ARGS 100
|
||||
|
||||
#include <apr_thread_proc.h>
|
||||
|
||||
typedef struct Shell {
|
||||
const char *dir;
|
||||
const char *exe;
|
||||
|
||||
apr_procattr_t *attr;
|
||||
apr_proc_t proc;
|
||||
apr_exit_why_e exit_why;
|
||||
int exit_code;
|
||||
|
||||
const char *args[MAX_COMMAND_ARGS];
|
||||
} Shell;
|
||||
|
||||
int Shell_run(apr_pool_t *p, Shell *cmd);
|
||||
int Shell_exec(Shell cmd, ...);
|
||||
|
||||
extern Shell CLEANUP_SH;
|
||||
extern Shell GIT_SH;
|
||||
extern Shell TAR_SH;
|
||||
extern Shell CURL_SH;
|
||||
extern Shell CONFIGURE_SH;
|
||||
extern Shell MAKE_SH;
|
||||
extern Shell INSTALL_SH;
|
||||
|
||||
#endif
|
8
oldstuff/lcthw-remnants-2/ex1.c
Normal file
8
oldstuff/lcthw-remnants-2/ex1.c
Normal file
@@ -0,0 +1,8 @@
|
||||
#include <stdio.h>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
puts("Hello world.");
|
||||
|
||||
return 0;
|
||||
}
|
25
oldstuff/lcthw-remnants-2/ex10.c
Normal file
25
oldstuff/lcthw-remnants-2/ex10.c
Normal file
@@ -0,0 +1,25 @@
|
||||
#include <stdio.h>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
// go through each string in argv
|
||||
// why am I skipping argv[0];
|
||||
for(i = 1; i < argc; i++) {
|
||||
printf("arg %d: %s\n", i, argv[i]);
|
||||
}
|
||||
|
||||
// let's make our own array of strings
|
||||
char *states[] = {
|
||||
"California", "Oregon",
|
||||
"Washington", "Texas"
|
||||
};
|
||||
int num_states = 4;
|
||||
|
||||
for(i = 0; i < num_states; i++) {
|
||||
printf("state %d: %s\n", i, states[i]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
27
oldstuff/lcthw-remnants-2/ex11.c
Normal file
27
oldstuff/lcthw-remnants-2/ex11.c
Normal file
@@ -0,0 +1,27 @@
|
||||
#include <stdio.h>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
// go through each string in argv
|
||||
|
||||
int i = 0;
|
||||
while(i < argc) {
|
||||
printf("arg %d: %s\n", i, argv[i]);
|
||||
i++;
|
||||
}
|
||||
|
||||
// let's make our own array of strings
|
||||
char *states[] = {
|
||||
"California", "Oregon",
|
||||
"Washington", "Texas"
|
||||
};
|
||||
|
||||
int num_states = 4;
|
||||
i = 0; // watch for this
|
||||
while(i < num_states) {
|
||||
printf("state %d: %s\n", i, states[i]);
|
||||
i++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
21
oldstuff/lcthw-remnants-2/ex12.c
Normal file
21
oldstuff/lcthw-remnants-2/ex12.c
Normal file
@@ -0,0 +1,21 @@
|
||||
#include <stdio.h>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
if(argc == 1) {
|
||||
printf("You only have one argument. You suck.\n");
|
||||
} else if(argc > 1 && argc < 4) {
|
||||
printf("Here's your arguments:\n");
|
||||
|
||||
for(i = 0; i < argc; i++) {
|
||||
printf("%s ", argv[i]);
|
||||
}
|
||||
printf("\n");
|
||||
} else {
|
||||
printf("You have too many arguments. You suck.\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
55
oldstuff/lcthw-remnants-2/ex13.c
Normal file
55
oldstuff/lcthw-remnants-2/ex13.c
Normal file
@@ -0,0 +1,55 @@
|
||||
#include <stdio.h>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
if(argc != 2) {
|
||||
printf("ERROR: You need one argument.\n");
|
||||
// this is how you abort a program
|
||||
return 1;
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
for(i = 0; argv[1][i] != '\0'; i++) {
|
||||
char letter = argv[1][i];
|
||||
|
||||
switch(letter) {
|
||||
case 'a':
|
||||
case 'A':
|
||||
printf("%d: 'A'\n", i);
|
||||
break;
|
||||
|
||||
case 'e':
|
||||
case 'E':
|
||||
printf("%d: 'E'\n", i);
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
case 'I':
|
||||
printf("%d: 'I'\n", i);
|
||||
break;
|
||||
|
||||
case 'o':
|
||||
case 'O':
|
||||
printf("%d: 'O'\n", i);
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
case 'U':
|
||||
printf("%d: 'U'\n", i);
|
||||
break;
|
||||
|
||||
case 'y':
|
||||
case 'Y':
|
||||
if(i > 2) {
|
||||
// it's only sometimes y
|
||||
printf("%d: 'Y'\n", i);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("%d: %c is not a vowel\n", i, letter);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
41
oldstuff/lcthw-remnants-2/ex14.c
Normal file
41
oldstuff/lcthw-remnants-2/ex14.c
Normal file
@@ -0,0 +1,41 @@
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
|
||||
// forward declarations
|
||||
int can_print_it(char ch);
|
||||
void print_letters(char arg[]);
|
||||
|
||||
void print_arguments(int argc, char *argv[])
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
for(i = 0; i < argc; i++) {
|
||||
print_letters(argv[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void print_letters(char arg[])
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
for(i = 0; arg[i] != '\0'; i++) {
|
||||
char ch = arg[i];
|
||||
|
||||
if(can_print_it(ch)) {
|
||||
printf("'%c' == %d ", ch, ch);
|
||||
}
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
int can_print_it(char ch)
|
||||
{
|
||||
return isalpha(ch) || isblank(ch);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
print_arguments(argc, argv);
|
||||
return 0;
|
||||
}
|
54
oldstuff/lcthw-remnants-2/ex15.c
Normal file
54
oldstuff/lcthw-remnants-2/ex15.c
Normal file
@@ -0,0 +1,54 @@
|
||||
#include <stdio.h>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
// create two arrays we care about
|
||||
int ages[] = {23, 43, 12, 89, 2};
|
||||
char *names[] = {
|
||||
"Alan", "Frank",
|
||||
"Mary", "John", "Lisa"
|
||||
};
|
||||
|
||||
// safely get the size of ages
|
||||
int count = sizeof(ages) / sizeof(int);
|
||||
int i = 0;
|
||||
|
||||
// first way using indexing
|
||||
for(i = 0; i < count; i++) {
|
||||
printf("%s has %d years alive.\n",
|
||||
names[i], ages[i]);
|
||||
}
|
||||
|
||||
printf("---\n");
|
||||
|
||||
// setup the pointers to the start of the arrays
|
||||
int *cur_age = ages;
|
||||
char **cur_name = names;
|
||||
|
||||
// second way using pointers
|
||||
for(i = 0; i < count; i++) {
|
||||
printf("%s is %d years old.\n",
|
||||
*(cur_name+i), *(cur_age+i));
|
||||
}
|
||||
|
||||
printf("---\n");
|
||||
|
||||
// third way, pointers are just arrays
|
||||
for(i = 0; i < count; i++) {
|
||||
printf("%s is %d years old again.\n",
|
||||
cur_name[i], cur_age[i]);
|
||||
}
|
||||
|
||||
printf("---\n");
|
||||
|
||||
// fourth way with pointers in a stupid complex way
|
||||
for(cur_name = names, cur_age = ages;
|
||||
(cur_age - ages) < count;
|
||||
cur_name++, cur_age++)
|
||||
{
|
||||
printf("%s lived %d years so far.\n",
|
||||
*cur_name, *cur_age);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
73
oldstuff/lcthw-remnants-2/ex16.c
Normal file
73
oldstuff/lcthw-remnants-2/ex16.c
Normal file
@@ -0,0 +1,73 @@
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
struct Person {
|
||||
char *name;
|
||||
int age;
|
||||
int height;
|
||||
int weight;
|
||||
};
|
||||
|
||||
struct Person *Person_create(char *name, int age, int height, int weight)
|
||||
{
|
||||
struct Person *who = malloc(sizeof(struct Person));
|
||||
assert(who != NULL);
|
||||
|
||||
who->name = strdup(name);
|
||||
who->age = age;
|
||||
who->height = height;
|
||||
who->weight = weight;
|
||||
|
||||
return who;
|
||||
}
|
||||
|
||||
void Person_destroy(struct Person *who)
|
||||
{
|
||||
assert(who != NULL);
|
||||
|
||||
free(who->name);
|
||||
free(who);
|
||||
}
|
||||
|
||||
void Person_print(struct Person *who)
|
||||
{
|
||||
printf("Name: %s\n", who->name);
|
||||
printf("\tAge: %d\n", who->age);
|
||||
printf("\tHeight: %d\n", who->height);
|
||||
printf("\tWeight: %d\n", who->weight);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
// make two people structures
|
||||
struct Person *joe = Person_create(
|
||||
"Joe Alex", 32, 64, 140);
|
||||
|
||||
struct Person *frank = Person_create(
|
||||
"Frank Blank", 20, 72, 180);
|
||||
|
||||
// print them out and where they are in memory
|
||||
printf("Joe is at memory location %p:\n", joe);
|
||||
Person_print(joe);
|
||||
|
||||
printf("Frank is at memory location %p:\n", frank);
|
||||
Person_print(frank);
|
||||
|
||||
// make everyone age 20 years and print them again
|
||||
joe->age += 20;
|
||||
joe->height -= 2;
|
||||
joe->weight += 40;
|
||||
Person_print(joe);
|
||||
|
||||
frank->age += 20;
|
||||
frank->weight += 20;
|
||||
Person_print(frank);
|
||||
|
||||
// destroy them both so we clean up
|
||||
Person_destroy(joe);
|
||||
Person_destroy(frank);
|
||||
|
||||
return 0;
|
||||
}
|
234
oldstuff/lcthw-remnants-2/ex17-ec.c
Normal file
234
oldstuff/lcthw-remnants-2/ex17-ec.c
Normal file
@@ -0,0 +1,234 @@
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <libgen.h>
|
||||
|
||||
#define MAX_DATA 512
|
||||
#define MAX_ROWS 100
|
||||
|
||||
struct Address {
|
||||
int id;
|
||||
int set;
|
||||
char name[MAX_DATA];
|
||||
char email[MAX_DATA];
|
||||
char street[MAX_DATA];
|
||||
};
|
||||
|
||||
struct Database {
|
||||
struct Address rows[MAX_ROWS];
|
||||
};
|
||||
|
||||
struct Connection {
|
||||
FILE *file;
|
||||
struct Database *db;
|
||||
};
|
||||
|
||||
void Database_close(struct Connection *conn);
|
||||
|
||||
void die(const char *message, struct Connection *conn)
|
||||
{
|
||||
if(errno) {
|
||||
perror(message);
|
||||
} else {
|
||||
printf("ERROR: %s\n", message);
|
||||
}
|
||||
|
||||
Database_close(conn);
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void Address_print(struct Address *addr)
|
||||
{
|
||||
printf("%d %s %s \"%s\"\n",
|
||||
addr->id, addr->name, addr->email, addr->street);
|
||||
}
|
||||
|
||||
void Database_load(struct Connection *conn)
|
||||
{
|
||||
int rc = fread(conn->db, sizeof(struct Database), 1, conn->file);
|
||||
if(rc != 1) die("Failed to load database.", conn);
|
||||
}
|
||||
|
||||
struct Connection *Database_open(const char *filename, char mode)
|
||||
{
|
||||
struct Connection *conn = malloc(sizeof(struct Connection));
|
||||
if(!conn) die("Memory error", conn);
|
||||
|
||||
conn->db = malloc(sizeof(struct Database));
|
||||
if(!conn->db) die("Memory error", conn);
|
||||
|
||||
if(mode == 'c') {
|
||||
conn->file = fopen(filename, "w");
|
||||
} else {
|
||||
conn->file = fopen(filename, "r+");
|
||||
|
||||
if(conn->file) {
|
||||
Database_load(conn);
|
||||
}
|
||||
}
|
||||
|
||||
if(!conn->file) die("Failed to open the file", conn);
|
||||
|
||||
return conn;
|
||||
}
|
||||
|
||||
void Database_close(struct Connection *conn)
|
||||
{
|
||||
if(conn) {
|
||||
if(conn->file) fclose(conn->file);
|
||||
if(conn->db) free(conn->db);
|
||||
free(conn);
|
||||
}
|
||||
}
|
||||
|
||||
void Database_write(struct Connection *conn)
|
||||
{
|
||||
rewind(conn->file);
|
||||
|
||||
int rc = fwrite(conn->db, sizeof(struct Database), 1, conn->file);
|
||||
if(rc != 1) die("Failed to write database.", conn);
|
||||
|
||||
rc = fflush(conn->file);
|
||||
if(rc == -1) die("Connot flush database.", conn);
|
||||
}
|
||||
|
||||
void Database_create(struct Connection *conn)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
for(i = 0; i < MAX_ROWS; i++) {
|
||||
// make a prototype to initialize it
|
||||
struct Address addr = {.id = i, .set = 0};
|
||||
// then just assign it
|
||||
conn->db->rows[i] = addr;
|
||||
}
|
||||
}
|
||||
|
||||
void Database_set(struct Connection *conn, int id, const char *name,
|
||||
const char *email, const char *street)
|
||||
{
|
||||
struct Address *addr = &conn->db->rows[id];
|
||||
if(addr->set) die("Already set, delete it first", conn);
|
||||
|
||||
addr->set = 1;
|
||||
// WARNING: bug, read the "How To Break It" and fix this
|
||||
char *res = strncpy(addr->name, name, MAX_DATA);
|
||||
// demonstrate the strncpy bug
|
||||
if(!res) die("Name copy failed", conn);
|
||||
|
||||
res = strncpy(addr->email, email, MAX_DATA);
|
||||
if(!res) die("Email copy failed", conn);
|
||||
|
||||
res = strncpy(addr->street, street, MAX_DATA);
|
||||
if(!res) die("Street copy failed", conn);
|
||||
}
|
||||
|
||||
void Database_get(struct Connection *conn, int id)
|
||||
{
|
||||
struct Address *addr = &conn->db->rows[id];
|
||||
|
||||
if(addr->set) {
|
||||
Address_print(addr);
|
||||
} else {
|
||||
die("ID is not set", conn);
|
||||
}
|
||||
}
|
||||
|
||||
void Database_delete(struct Connection *conn, int id)
|
||||
{
|
||||
struct Address addr = {.id = id, .set = 0};
|
||||
conn->db->rows[id] = addr;
|
||||
}
|
||||
|
||||
void Database_list(struct Connection *conn)
|
||||
{
|
||||
int i = 0;
|
||||
struct Database *db = conn->db;
|
||||
|
||||
for(i = 0; i < MAX_ROWS; i++) {
|
||||
struct Address *cur = &db->rows[i];
|
||||
|
||||
if(cur->set) {
|
||||
Address_print(cur);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Database_find(struct Connection *conn, char *search)
|
||||
{
|
||||
int i = 0;
|
||||
struct Database *db = conn->db;
|
||||
|
||||
for(i = 0; i < MAX_ROWS; i++) {
|
||||
struct Address *cur = &db->rows[i];
|
||||
|
||||
if(cur->set) {
|
||||
if(strstr(cur->email, search) != NULL ||
|
||||
strstr(cur->name, search) != NULL ||
|
||||
strstr(cur->street, search) != NULL) {
|
||||
Address_print(cur);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char usage[64];
|
||||
sprintf(usage, "USAGE: %s <dbfile> <action> [action params]", basename(argv[0]));
|
||||
|
||||
if(argc < 3) die(usage, NULL);
|
||||
|
||||
char *filename = argv[1];
|
||||
char action = argv[2][0];
|
||||
struct Connection *conn = Database_open(filename, action);
|
||||
int id = 0;
|
||||
|
||||
if(argc > 3) id = atoi(argv[3]);
|
||||
if(id >= MAX_ROWS) die("There's not that many records.", conn);
|
||||
|
||||
switch(action) {
|
||||
case 'c':
|
||||
Database_create(conn);
|
||||
Database_write(conn);
|
||||
break;
|
||||
|
||||
case 'g':
|
||||
if(argc != 4) die("Need an id to get", conn);
|
||||
|
||||
Database_get(conn, id);
|
||||
break;
|
||||
|
||||
case 's':
|
||||
if(argc != 7) die("Need id, name, email, and street to set", conn);
|
||||
|
||||
Database_set(conn, id, argv[4], argv[5], argv[6]);
|
||||
Database_write(conn);
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
if(argc != 4) die("Need id to delete", conn);
|
||||
|
||||
Database_delete(conn, id);
|
||||
Database_write(conn);
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
if(argc != 4) die("Need something to find", conn);
|
||||
Database_find(conn, argv[3]);
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
Database_list(conn);
|
||||
break;
|
||||
default:
|
||||
die("Invalid action, only: c=create, g=get, s=set, d=del, l=list, f=find", conn);
|
||||
}
|
||||
|
||||
Database_close(conn);
|
||||
|
||||
return 0;
|
||||
}
|
86
oldstuff/lcthw-remnants-2/ex17-ec2.c
Normal file
86
oldstuff/lcthw-remnants-2/ex17-ec2.c
Normal file
@@ -0,0 +1,86 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define MAX_STACK 1024
|
||||
#define STACK_SENTINEL -1
|
||||
|
||||
struct Stack {
|
||||
int l[MAX_STACK];
|
||||
};
|
||||
|
||||
struct Stack *Stack_create()
|
||||
{
|
||||
struct Stack *s = malloc(sizeof(struct Stack));
|
||||
if(!s) { return NULL; }
|
||||
|
||||
int i = 0;
|
||||
|
||||
for(i = 0; i < MAX_STACK; i++) {
|
||||
s->l[i] = STACK_SENTINEL;
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
int Stack_push(struct Stack *s, int v)
|
||||
{
|
||||
if(v <= STACK_SENTINEL) {
|
||||
return STACK_SENTINEL;
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
for(i = 0; i < MAX_STACK; i++) {
|
||||
if(s->l[i] == STACK_SENTINEL) {
|
||||
s->l[i] = v;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return STACK_SENTINEL;
|
||||
}
|
||||
|
||||
int Stack_pop(struct Stack *s)
|
||||
{
|
||||
int i = 0;
|
||||
int v = 0;
|
||||
for(i = 0; i < MAX_STACK; i++) {
|
||||
if(s->l[i] == STACK_SENTINEL) {
|
||||
v = s->l[i-1];
|
||||
s->l[i-1] = STACK_SENTINEL;
|
||||
return v;
|
||||
}
|
||||
}
|
||||
|
||||
return STACK_SENTINEL;
|
||||
}
|
||||
|
||||
int Stack_size(struct Stack *s)
|
||||
{
|
||||
int i = 0;
|
||||
for(i = 0; i < MAX_STACK; i++) {
|
||||
if(s->l[i] == STACK_SENTINEL) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return STACK_SENTINEL;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
struct Stack *s = Stack_create();
|
||||
|
||||
printf("size: %d\n", Stack_size(s));
|
||||
Stack_push(s, 10);
|
||||
Stack_push(s, 20);
|
||||
Stack_push(s, 40);
|
||||
|
||||
printf("size: %d\n", Stack_size(s));
|
||||
printf("pop: %d\n", Stack_pop(s));
|
||||
printf("pop: %d\n", Stack_pop(s));
|
||||
printf("size: %d\n", Stack_size(s));
|
||||
printf("pop: %d\n", Stack_pop(s));
|
||||
printf("pop: %d\n", Stack_pop(s));
|
||||
|
||||
return 0;
|
||||
}
|
198
oldstuff/lcthw-remnants-2/ex17.c
Normal file
198
oldstuff/lcthw-remnants-2/ex17.c
Normal file
@@ -0,0 +1,198 @@
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#define MAX_DATA 512
|
||||
#define MAX_ROWS 100
|
||||
|
||||
struct Address {
|
||||
int id;
|
||||
int set;
|
||||
char name[MAX_DATA];
|
||||
char email[MAX_DATA];
|
||||
};
|
||||
|
||||
struct Database {
|
||||
struct Address rows[MAX_ROWS];
|
||||
};
|
||||
|
||||
struct Connection {
|
||||
FILE *file;
|
||||
struct Database *db;
|
||||
};
|
||||
|
||||
void die(const char *message)
|
||||
{
|
||||
if(errno) {
|
||||
perror(message);
|
||||
} else {
|
||||
printf("ERROR: %s\n", message);
|
||||
}
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void Address_print(struct Address *addr)
|
||||
{
|
||||
printf("%d %s %s\n",
|
||||
addr->id, addr->name, addr->email);
|
||||
}
|
||||
|
||||
void Database_load(struct Connection *conn)
|
||||
{
|
||||
int rc = fread(conn->db, sizeof(struct Database), 1, conn->file);
|
||||
if(rc != 1) die("Failed to load database.");
|
||||
}
|
||||
|
||||
struct Connection *Database_open(const char *filename, char mode)
|
||||
{
|
||||
struct Connection *conn = malloc(sizeof(struct Connection));
|
||||
if(!conn) die("Memory error");
|
||||
|
||||
conn->db = malloc(sizeof(struct Database));
|
||||
if(!conn->db) die("Memory error");
|
||||
|
||||
if(mode == 'c') {
|
||||
conn->file = fopen(filename, "w");
|
||||
} else {
|
||||
conn->file = fopen(filename, "r+");
|
||||
|
||||
if(conn->file) {
|
||||
Database_load(conn);
|
||||
}
|
||||
}
|
||||
|
||||
if(!conn->file) die("Failed to open the file");
|
||||
|
||||
return conn;
|
||||
}
|
||||
|
||||
void Database_close(struct Connection *conn)
|
||||
{
|
||||
if(conn) {
|
||||
if(conn->file) fclose(conn->file);
|
||||
if(conn->db) free(conn->db);
|
||||
free(conn);
|
||||
}
|
||||
}
|
||||
|
||||
void Database_write(struct Connection *conn)
|
||||
{
|
||||
rewind(conn->file);
|
||||
|
||||
int rc = fwrite(conn->db, sizeof(struct Database), 1, conn->file);
|
||||
if(rc != 1) die("Failed to write database.");
|
||||
|
||||
rc = fflush(conn->file);
|
||||
if(rc == -1) die("Connot flush database.");
|
||||
}
|
||||
|
||||
void Database_create(struct Connection *conn)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
for(i = 0; i < MAX_ROWS; i++) {
|
||||
// make a prototype to initialize it
|
||||
struct Address addr = {.id = i, .set = 0};
|
||||
// then just assign it
|
||||
conn->db->rows[i] = addr;
|
||||
}
|
||||
}
|
||||
|
||||
void Database_set(struct Connection *conn, int id, const char *name, const char *email)
|
||||
{
|
||||
struct Address *addr = &conn->db->rows[id];
|
||||
if(addr->set) die("Already set, delete it first");
|
||||
|
||||
addr->set = 1;
|
||||
// WARNING: bug, read the "How To Break It" and fix this
|
||||
char *res = strncpy(addr->name, name, MAX_DATA);
|
||||
// demonstrate the strncpy bug
|
||||
if(!res) die("Name copy failed");
|
||||
|
||||
res = strncpy(addr->email, email, MAX_DATA);
|
||||
if(!res) die("Email copy failed");
|
||||
}
|
||||
|
||||
void Database_get(struct Connection *conn, int id)
|
||||
{
|
||||
struct Address *addr = &conn->db->rows[id];
|
||||
|
||||
if(addr->set) {
|
||||
Address_print(addr);
|
||||
} else {
|
||||
die("ID is not set");
|
||||
}
|
||||
}
|
||||
|
||||
void Database_delete(struct Connection *conn, int id)
|
||||
{
|
||||
struct Address addr = {.id = id, .set = 0};
|
||||
conn->db->rows[id] = addr;
|
||||
}
|
||||
|
||||
void Database_list(struct Connection *conn)
|
||||
{
|
||||
int i = 0;
|
||||
struct Database *db = conn->db;
|
||||
|
||||
for(i = 0; i < MAX_ROWS; i++) {
|
||||
struct Address *cur = &db->rows[i];
|
||||
|
||||
if(cur->set) {
|
||||
Address_print(cur);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
if(argc < 3) die("USAGE: ex17 <dbfile> <action> [action params]");
|
||||
|
||||
char *filename = argv[1];
|
||||
char action = argv[2][0];
|
||||
struct Connection *conn = Database_open(filename, action);
|
||||
int id = 0;
|
||||
|
||||
if(argc > 3) id = atoi(argv[3]);
|
||||
if(id >= MAX_ROWS) die("There's not that many records.");
|
||||
|
||||
switch(action) {
|
||||
case 'c':
|
||||
Database_create(conn);
|
||||
Database_write(conn);
|
||||
break;
|
||||
|
||||
case 'g':
|
||||
if(argc != 4) die("Need an id to get");
|
||||
|
||||
Database_get(conn, id);
|
||||
break;
|
||||
|
||||
case 's':
|
||||
if(argc != 6) die("Need id, name, email to set");
|
||||
|
||||
Database_set(conn, id, argv[4], argv[5]);
|
||||
Database_write(conn);
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
if(argc != 4) die("Need id to delete");
|
||||
|
||||
Database_delete(conn, id);
|
||||
Database_write(conn);
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
Database_list(conn);
|
||||
break;
|
||||
default:
|
||||
die("Invalid action, only: c=create, g=get, s=set, d=del, l=list");
|
||||
}
|
||||
|
||||
Database_close(conn);
|
||||
|
||||
return 0;
|
||||
}
|
119
oldstuff/lcthw-remnants-2/ex18-ec.c
Normal file
119
oldstuff/lcthw-remnants-2/ex18-ec.c
Normal file
@@ -0,0 +1,119 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
/** Our old friend die from ex17. */
|
||||
void die(const char *message)
|
||||
{
|
||||
if(errno) {
|
||||
perror(message);
|
||||
} else {
|
||||
printf("ERROR: %s\n", message);
|
||||
}
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// a typedef creates a fake type, in this
|
||||
// case for a function pointer
|
||||
typedef int (*compare_cb)(int a, int b);
|
||||
|
||||
/**
|
||||
* A classic bubble sort function that uses the
|
||||
* compare_cb to do the sorting.
|
||||
*/
|
||||
int *bubble_sort(int *numbers, int count, compare_cb cmp)
|
||||
{
|
||||
int temp = 0;
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
int *target = malloc(count * sizeof(int));
|
||||
|
||||
if(!target) die("Memory error.");
|
||||
|
||||
memcpy(target, numbers, count * sizeof(int));
|
||||
|
||||
for(i = 0; i < count; i++) {
|
||||
for(j = 0; j < count - 1; j++) {
|
||||
if(cmp(target[j], target[j+1]) > 0) {
|
||||
temp = target[j+1];
|
||||
target[j+1] = target[j];
|
||||
target[j] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
int sorted_order(int a, int b)
|
||||
{
|
||||
return a - b;
|
||||
}
|
||||
|
||||
int reverse_order(int a, int b)
|
||||
{
|
||||
return b - a;
|
||||
}
|
||||
|
||||
int strange_order(int a, int b)
|
||||
{
|
||||
if(a == 0 || b == 0) {
|
||||
return 0;
|
||||
} else {
|
||||
return a % b;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to test that we are sorting things correctly
|
||||
* by doing the sort and printing it out.
|
||||
*/
|
||||
void test_sorting(int *numbers, int count, compare_cb cmp)
|
||||
{
|
||||
int i = 0;
|
||||
int *sorted = bubble_sort(numbers, count, cmp);
|
||||
|
||||
if(!sorted) die("Failed to sort as requested.");
|
||||
|
||||
for(i = 0; i < count; i++) {
|
||||
printf("%d ", sorted[i]);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
free(sorted);
|
||||
|
||||
unsigned char *data = (unsigned char *)cmp;
|
||||
|
||||
for(i = 0; i < 25; i++) {
|
||||
printf("%02x:", data[i]);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
if(argc < 2) die("USAGE: ex18 4 3 1 5 6");
|
||||
|
||||
int count = argc - 1;
|
||||
int i = 0;
|
||||
char **inputs = argv + 1;
|
||||
|
||||
int *numbers = malloc(count * sizeof(int));
|
||||
if(!numbers) die("Memory error.");
|
||||
|
||||
for(i = 0; i < count; i++) {
|
||||
numbers[i] = atoi(inputs[i]);
|
||||
}
|
||||
|
||||
test_sorting(numbers, count, sorted_order);
|
||||
test_sorting(numbers, count, reverse_order);
|
||||
test_sorting(numbers, count, strange_order);
|
||||
|
||||
free(numbers);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
111
oldstuff/lcthw-remnants-2/ex18.c
Normal file
111
oldstuff/lcthw-remnants-2/ex18.c
Normal file
@@ -0,0 +1,111 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
/** Our old friend die from ex17. */
|
||||
void die(const char *message)
|
||||
{
|
||||
if(errno) {
|
||||
perror(message);
|
||||
} else {
|
||||
printf("ERROR: %s\n", message);
|
||||
}
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// a typedef creates a fake type, in this
|
||||
// case for a function pointer
|
||||
typedef int (*compare_cb)(int a, int b);
|
||||
|
||||
/**
|
||||
* A classic bubble sort function that uses the
|
||||
* compare_cb to do the sorting.
|
||||
*/
|
||||
int *bubble_sort(int *numbers, int count, compare_cb cmp)
|
||||
{
|
||||
int temp = 0;
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
int *target = malloc(count * sizeof(int));
|
||||
|
||||
if(!target) die("Memory error.");
|
||||
|
||||
memcpy(target, numbers, count * sizeof(int));
|
||||
|
||||
for(i = 0; i < count; i++) {
|
||||
for(j = 0; j < count - 1; j++) {
|
||||
if(cmp(target[j], target[j+1]) > 0) {
|
||||
temp = target[j+1];
|
||||
target[j+1] = target[j];
|
||||
target[j] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
int sorted_order(int a, int b)
|
||||
{
|
||||
return a - b;
|
||||
}
|
||||
|
||||
int reverse_order(int a, int b)
|
||||
{
|
||||
return b - a;
|
||||
}
|
||||
|
||||
int strange_order(int a, int b)
|
||||
{
|
||||
if(a == 0 || b == 0) {
|
||||
return 0;
|
||||
} else {
|
||||
return a % b;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to test that we are sorting things correctly
|
||||
* by doing the sort and printing it out.
|
||||
*/
|
||||
void test_sorting(int *numbers, int count, compare_cb cmp)
|
||||
{
|
||||
int i = 0;
|
||||
int *sorted = bubble_sort(numbers, count, cmp);
|
||||
|
||||
if(!sorted) die("Failed to sort as requested.");
|
||||
|
||||
for(i = 0; i < count; i++) {
|
||||
printf("%d ", sorted[i]);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
free(sorted);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
if(argc < 2) die("USAGE: ex18 4 3 1 5 6");
|
||||
|
||||
int count = argc - 1;
|
||||
int i = 0;
|
||||
char **inputs = argv + 1;
|
||||
|
||||
int *numbers = malloc(count * sizeof(int));
|
||||
if(!numbers) die("Memory error.");
|
||||
|
||||
for(i = 0; i < count; i++) {
|
||||
numbers[i] = atoi(inputs[i]);
|
||||
}
|
||||
|
||||
test_sorting(numbers, count, sorted_order);
|
||||
test_sorting(numbers, count, reverse_order);
|
||||
test_sorting(numbers, count, strange_order);
|
||||
|
||||
free(numbers);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
225
oldstuff/lcthw-remnants-2/ex19.c
Normal file
225
oldstuff/lcthw-remnants-2/ex19.c
Normal file
@@ -0,0 +1,225 @@
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <assert.h>
|
||||
#include "ex19.h"
|
||||
|
||||
|
||||
int Monster_attack(void *self, int damage)
|
||||
{
|
||||
assert(self != NULL);
|
||||
Monster *monster = self;
|
||||
|
||||
printf("You attack %s!\n", monster->_(description));
|
||||
|
||||
monster->hit_points -= damage;
|
||||
|
||||
if(monster->hit_points > 0) {
|
||||
printf("It is still alive.\n");
|
||||
return 0;
|
||||
} else {
|
||||
printf("It is dead!\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
int Monster_init(void *self)
|
||||
{
|
||||
assert(self != NULL);
|
||||
Monster *monster = self;
|
||||
monster->hit_points = 10;
|
||||
return 1;
|
||||
}
|
||||
|
||||
Object MonsterProto = {
|
||||
.init = Monster_init,
|
||||
.attack = Monster_attack
|
||||
};
|
||||
|
||||
|
||||
void *Room_move(void *self, Direction direction)
|
||||
{
|
||||
assert(self != NULL);
|
||||
Room *room = self;
|
||||
Room *next = NULL;
|
||||
|
||||
if(direction == NORTH && room->north) {
|
||||
printf("You go north, into:\n");
|
||||
next = room->north;
|
||||
} else if(direction == SOUTH && room->south) {
|
||||
printf("You go south, into:\n");
|
||||
next = room->south;
|
||||
} else if(direction == EAST && room->east) {
|
||||
printf("You go east, into:\n");
|
||||
next = room->east;
|
||||
} else if(direction == WEST && room->west) {
|
||||
printf("You go west, into:\n");
|
||||
next = room->west;
|
||||
} else {
|
||||
printf("You can't go that direction.");
|
||||
next = NULL;
|
||||
}
|
||||
|
||||
if(next) {
|
||||
next->_(describe)(next);
|
||||
}
|
||||
|
||||
return next;
|
||||
}
|
||||
|
||||
|
||||
int Room_attack(void *self, int damage)
|
||||
{
|
||||
assert(self != NULL);
|
||||
Room *room = self;
|
||||
Monster *monster = room->bad_guy;
|
||||
|
||||
if(monster) {
|
||||
monster->_(attack)(monster, damage);
|
||||
return 1;
|
||||
} else {
|
||||
printf("You flail in the air at nothing. Idiot.\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Object RoomProto = {
|
||||
.move = Room_move,
|
||||
.attack = Room_attack
|
||||
};
|
||||
|
||||
|
||||
void *Map_move(void *self, Direction direction)
|
||||
{
|
||||
assert(self != NULL);
|
||||
Map *map = self;
|
||||
Room *location = map->location;
|
||||
Room *next = NULL;
|
||||
|
||||
next = location->_(move)(location, direction);
|
||||
|
||||
if(next) {
|
||||
map->location = next;
|
||||
}
|
||||
|
||||
return next;
|
||||
}
|
||||
|
||||
int Map_attack(void *self, int damage)
|
||||
{
|
||||
assert(self != NULL);
|
||||
Map *map = self;
|
||||
Room *location = map->location;
|
||||
|
||||
return location->_(attack)(location, damage);
|
||||
}
|
||||
|
||||
|
||||
int Map_init(void *self)
|
||||
{
|
||||
assert(self != NULL);
|
||||
Map *map = self;
|
||||
|
||||
// make some rooms for a small map
|
||||
Room *hall = NEW(Room, "The great Hall");
|
||||
Room *throne = NEW(Room, "The throne room");
|
||||
Room *arena = NEW(Room, "The arena, with the minotaur");
|
||||
Room *kitchen = NEW(Room, "Kitchen, you have the knife now");
|
||||
|
||||
// put the bad guy in the arena
|
||||
arena->bad_guy = NEW(Monster, "The evil minotaur");
|
||||
|
||||
// setup the map rooms
|
||||
hall->north = throne;
|
||||
|
||||
throne->west = arena;
|
||||
throne->east = kitchen;
|
||||
throne->south = hall;
|
||||
|
||||
arena->east = throne;
|
||||
kitchen->west = throne;
|
||||
|
||||
// start the map and the characters off in the hall
|
||||
map->start = hall;
|
||||
map->location = hall;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
Object MapProto = {
|
||||
.init = Map_init,
|
||||
.move = Map_move,
|
||||
.attack = Map_attack
|
||||
};
|
||||
|
||||
int process_input(Map *game)
|
||||
{
|
||||
assert(game != NULL);
|
||||
printf("\n> ");
|
||||
|
||||
char ch = getchar();
|
||||
getchar(); // eat ENTER
|
||||
|
||||
int damage = rand() % 4;
|
||||
|
||||
switch(ch) {
|
||||
case -1:
|
||||
printf("Giving up? You suck.\n");
|
||||
return 0;
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
game->_(move)(game, NORTH);
|
||||
break;
|
||||
|
||||
case 's':
|
||||
game->_(move)(game, SOUTH);
|
||||
break;
|
||||
|
||||
case 'e':
|
||||
game->_(move)(game, EAST);
|
||||
break;
|
||||
|
||||
case 'w':
|
||||
game->_(move)(game, WEST);
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
game->_(attack)(game, damage);
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
printf("You can go:\n");
|
||||
if(game->location->north) printf("NORTH\n");
|
||||
if(game->location->south) printf("SOUTH\n");
|
||||
if(game->location->east) printf("EAST\n");
|
||||
if(game->location->west) printf("WEST\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("What?: %d\n", ch);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
// simple way to setup the randomness
|
||||
srand(time(NULL));
|
||||
|
||||
// make our map to work with
|
||||
Map *game = NEW(Map, "The Hall of the Minotaur.");
|
||||
assert(game != NULL);
|
||||
|
||||
printf("You enter the ");
|
||||
game->location->_(describe)(game->location);
|
||||
|
||||
while(process_input(game)) {
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
118
oldstuff/lcthw-remnants-2/ex20.c
Normal file
118
oldstuff/lcthw-remnants-2/ex20.c
Normal file
@@ -0,0 +1,118 @@
|
||||
#include "dbg.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
void test_debug()
|
||||
{
|
||||
// notice you don't need the \n
|
||||
debug("I have Brown Hair.");
|
||||
|
||||
// passing in arguments like printf
|
||||
debug("I am %d years old.", 37);
|
||||
}
|
||||
|
||||
void test_log_err()
|
||||
{
|
||||
log_err("I believe everything is broken.");
|
||||
log_err("There are %d problems in %s.", 0, "space");
|
||||
}
|
||||
|
||||
void test_log_warn()
|
||||
{
|
||||
log_warn("You can safely ignore this.");
|
||||
log_warn("Maybe consider looking at: %s.", "/etc/passwd");
|
||||
}
|
||||
|
||||
void test_log_info()
|
||||
{
|
||||
log_info("Well I did something mundane.");
|
||||
log_info("It happened %f times today.", 1.3f);
|
||||
}
|
||||
|
||||
int test_check(char *file_name)
|
||||
{
|
||||
FILE *input = NULL;
|
||||
char *block = NULL;
|
||||
|
||||
block = malloc(100);
|
||||
check_mem(block); // should work
|
||||
|
||||
input = fopen(file_name, "r");
|
||||
check(input, "Failed to open %s.", file_name);
|
||||
|
||||
free(block);
|
||||
fclose(input);
|
||||
return 0;
|
||||
|
||||
error:
|
||||
if(block) free(block);
|
||||
if(input) fclose(input);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int test_sentinel(int code)
|
||||
{
|
||||
char *temp = malloc(100);
|
||||
check_mem(temp);
|
||||
|
||||
switch(code) {
|
||||
case 1:
|
||||
log_info("It worked.");
|
||||
break;
|
||||
default:
|
||||
sentinel("I shouldn't run.");
|
||||
}
|
||||
|
||||
free(temp);
|
||||
return 0;
|
||||
|
||||
error:
|
||||
if(temp) free(temp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int test_check_mem()
|
||||
{
|
||||
char *test = NULL;
|
||||
check_mem(test);
|
||||
|
||||
free(test);
|
||||
return 1;
|
||||
|
||||
error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
int test_check_debug()
|
||||
{
|
||||
int i = 0;
|
||||
check_debug(i != 0, "Oops, I was 0.");
|
||||
|
||||
return 0;
|
||||
error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
check(argc == 2, "Need an argument.");
|
||||
|
||||
test_debug();
|
||||
test_log_err();
|
||||
test_log_warn();
|
||||
test_log_info();
|
||||
|
||||
check(test_check("ex20.c") == 0, "failed with ex20.c");
|
||||
check(test_check(argv[1]) == -1, "failed with argv");
|
||||
check(test_sentinel(1) == 0, "test_sentinel failed.");
|
||||
check(test_sentinel(100) == -1, "test_sentinel failed.");
|
||||
check(test_check_mem() == -1, "test_check_mem failed.");
|
||||
check(test_check_debug() == -1, "test_check_debug failed.");
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
return 1;
|
||||
}
|
||||
|
33
oldstuff/lcthw-remnants-2/ex22.c
Normal file
33
oldstuff/lcthw-remnants-2/ex22.c
Normal file
@@ -0,0 +1,33 @@
|
||||
#include <stdio.h>
|
||||
#include "ex22.h"
|
||||
#include "dbg.h"
|
||||
|
||||
int THE_SIZE = 1000;
|
||||
|
||||
static int THE_AGE = 37;
|
||||
|
||||
int get_age()
|
||||
{
|
||||
return THE_AGE;
|
||||
}
|
||||
|
||||
void set_age(int age)
|
||||
{
|
||||
THE_AGE = age;
|
||||
}
|
||||
|
||||
|
||||
double update_ratio(double new_ratio)
|
||||
{
|
||||
static double ratio = 1.0;
|
||||
|
||||
double old_ratio = ratio;
|
||||
ratio = new_ratio;
|
||||
|
||||
return old_ratio;
|
||||
}
|
||||
|
||||
void print_size()
|
||||
{
|
||||
log_info("I think size is: %d", THE_SIZE);
|
||||
}
|
54
oldstuff/lcthw-remnants-2/ex22_main.c
Normal file
54
oldstuff/lcthw-remnants-2/ex22_main.c
Normal file
@@ -0,0 +1,54 @@
|
||||
#include "ex22.h"
|
||||
#include "dbg.h"
|
||||
|
||||
const char *MY_NAME = "Zed A. Shaw";
|
||||
|
||||
void scope_demo(int count)
|
||||
{
|
||||
log_info("count is: %d", count);
|
||||
|
||||
if(count > 10) {
|
||||
int count = 100; // BAD! BUGS!
|
||||
|
||||
log_info("count in this scope is %d", count);
|
||||
}
|
||||
|
||||
log_info("count is at exit: %d", count);
|
||||
|
||||
count = 3000;
|
||||
|
||||
log_info("count after assign: %d", count);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
// test out THE_AGE accessors
|
||||
log_info("My name: %s, age: %d", MY_NAME, get_age());
|
||||
|
||||
set_age(100);
|
||||
|
||||
log_info("My age is now: %d", get_age());
|
||||
|
||||
// test out THE_SIZE extern
|
||||
log_info("THE_SIZE is: %d", THE_SIZE);
|
||||
print_size();
|
||||
|
||||
THE_SIZE = 9;
|
||||
|
||||
log_info("THE_SIZE is now: %d", THE_SIZE);
|
||||
print_size();
|
||||
|
||||
// test the ration function static
|
||||
log_info("Ratio at first: %f", update_ratio(2.0));
|
||||
log_info("Ratio again: %f", update_ratio(10.0));
|
||||
log_info("Ratio once more: %f", update_ratio(300.0));
|
||||
|
||||
// test the scope demo
|
||||
int count = 4;
|
||||
scope_demo(count);
|
||||
scope_demo(count * 20);
|
||||
|
||||
log_info("count after calling scope_demo: %d", count);
|
||||
|
||||
return 0;
|
||||
}
|
109
oldstuff/lcthw-remnants-2/ex23.c
Normal file
109
oldstuff/lcthw-remnants-2/ex23.c
Normal file
@@ -0,0 +1,109 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "dbg.h"
|
||||
|
||||
int normal_copy(char *from, char *to, int count)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
for(i = 0; i < count; i++) {
|
||||
to[i] = from[i];
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
int duffs_device(char *from, char *to, int count)
|
||||
{
|
||||
{
|
||||
int n = (count + 7) / 8;
|
||||
debug("n=%d, (count %% 8)=%d", n, count % 8);
|
||||
|
||||
switch(count % 8) {
|
||||
case 0: do { *to++ = *from++;
|
||||
case 7: *to++ = *from++;
|
||||
case 6: *to++ = *from++;
|
||||
case 5: *to++ = *from++;
|
||||
case 4: *to++ = *from++;
|
||||
case 3: *to++ = *from++;
|
||||
case 2: *to++ = *from++;
|
||||
case 1: *to++ = *from++;
|
||||
} while(--n > 0);
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
int zeds_device(char *from, char *to, int count)
|
||||
{
|
||||
{
|
||||
int n = (count + 7) / 8;
|
||||
|
||||
switch(count % 8) {
|
||||
case 0:
|
||||
again: *to++ = *from++;
|
||||
case 7: *to++ = *from++;
|
||||
case 6: *to++ = *from++;
|
||||
case 5: *to++ = *from++;
|
||||
case 4: *to++ = *from++;
|
||||
case 3: *to++ = *from++;
|
||||
case 2: *to++ = *from++;
|
||||
case 1: *to++ = *from++;
|
||||
if(--n > 0) goto again;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
int valid_copy(char *data, int count, char expects)
|
||||
{
|
||||
int i = 0;
|
||||
for(i = 0; i < count; i++) {
|
||||
if(data[i] != expects) {
|
||||
log_err("[%d] %c != %c", i, data[i], expects);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char from[1000] = {'a'};
|
||||
char to[1000] = {'c'};
|
||||
int rc = 0;
|
||||
|
||||
// setup the from to have some stuff
|
||||
memset(from, 'x', 1000);
|
||||
// set it to a failure mode
|
||||
memset(to, 'y', 1000);
|
||||
check(valid_copy(to, 1000, 'y'), "Not initialized right.");
|
||||
|
||||
// use normal copy to
|
||||
rc = normal_copy(from, to, 1000);
|
||||
check(rc == 1000, "Normal copy failed: %d", rc);
|
||||
check(valid_copy(to, 1000, 'x'), "Normal copy failed.");
|
||||
|
||||
// reset
|
||||
memset(to, 'y', 1000);
|
||||
|
||||
// duffs version
|
||||
rc = duffs_device(from, to, 1000);
|
||||
check(rc == 1000, "Duff's deice failed: %d", rc);
|
||||
check(valid_copy(to, 1000, 'x'), "Duff's deice failed copy.");
|
||||
|
||||
// reset
|
||||
memset(to, 'y', 1000);
|
||||
|
||||
// my version
|
||||
rc = zeds_device(from, to, 1000);
|
||||
check(rc == 1000, "Zed's device failed: %d", rc);
|
||||
check(valid_copy(to, 1000, 'x'), "Zed's device failed copy.");
|
||||
|
||||
return 0;
|
||||
error:
|
||||
return 1;
|
||||
}
|
77
oldstuff/lcthw-remnants-2/ex24.c
Normal file
77
oldstuff/lcthw-remnants-2/ex24.c
Normal file
@@ -0,0 +1,77 @@
|
||||
#include <stdio.h>
|
||||
#include "dbg.h"
|
||||
|
||||
#define MAX_DATA 100
|
||||
|
||||
typedef enum EyeColor {
|
||||
BLUE_EYES, GREEN_EYES, BROWN_EYES,
|
||||
BLACK_EYES, OTHER_EYES
|
||||
} EyeColor;
|
||||
|
||||
const char *EYE_COLOR_NAMES[] = {
|
||||
"Blue", "Green", "Brown", "Black", "Other"
|
||||
};
|
||||
|
||||
typedef struct Person {
|
||||
int age;
|
||||
char first_name[MAX_DATA];
|
||||
char last_name[MAX_DATA];
|
||||
EyeColor eyes;
|
||||
float income;
|
||||
} Person;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
Person you = {.age = 0};
|
||||
int i = 0;
|
||||
int rc = -1;
|
||||
char *in = NULL;
|
||||
|
||||
printf("What's your First Name? ");
|
||||
in = fgets(you.first_name, MAX_DATA-1, stdin);
|
||||
check(in != NULL, "Failed to read first name.");
|
||||
|
||||
rc = sscanf(you.first_name, "%s", you.first_name);
|
||||
check(rc > 0, "Failed to strip first name.");
|
||||
|
||||
printf("What's your Last Name? ");
|
||||
in = fgets(you.last_name, MAX_DATA-1, stdin);
|
||||
check(in != NULL, "Failed to read last name.");
|
||||
|
||||
rc = sscanf(you.last_name, "%s", you.last_name);
|
||||
check(rc > 0, "Failed to strip last name.");
|
||||
|
||||
printf("How old are you? ");
|
||||
rc = fscanf(stdin, "%d", &you.age);
|
||||
check(rc > 0, "You have to enter a number.");
|
||||
|
||||
printf("What color are your eyes:\n");
|
||||
for(i = 0; i <= OTHER_EYES; i++) {
|
||||
printf("%d) %s\n", i+1, EYE_COLOR_NAMES[i]);
|
||||
}
|
||||
printf("> ");
|
||||
|
||||
int eyes = -1;
|
||||
rc = fscanf(stdin, "%d", &eyes);
|
||||
check(rc > 0, "You have to enter a number.");
|
||||
|
||||
you.eyes = eyes - 1;
|
||||
check(you.eyes <= OTHER_EYES && you.eyes >= 0, "Do it right, that's not an option.");
|
||||
|
||||
printf("How much do you make an hour? ");
|
||||
rc = fscanf(stdin, "%f", &you.income);
|
||||
check(rc > 0, "Enter a floating point number.");
|
||||
|
||||
printf("----- RESULTS -----\n");
|
||||
|
||||
printf("First Name: %s\n", you.first_name);
|
||||
printf("Last Name: %s\n", you.last_name);
|
||||
printf("Age: %d\n", you.age);
|
||||
printf("Eyes: %s\n", EYE_COLOR_NAMES[you.eyes]);
|
||||
printf("Income: %f\n", you.income);
|
||||
|
||||
return 0;
|
||||
error:
|
||||
|
||||
return -1;
|
||||
}
|
134
oldstuff/lcthw-remnants-2/ex25.c
Normal file
134
oldstuff/lcthw-remnants-2/ex25.c
Normal file
@@ -0,0 +1,134 @@
|
||||
/** WARNING: This code is fresh and potentially isn't correct yet. */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include "dbg.h"
|
||||
|
||||
#define MAX_DATA 100
|
||||
|
||||
int read_string(char **out_string, int max_buffer)
|
||||
{
|
||||
*out_string = calloc(1, max_buffer + 1);
|
||||
check_mem(*out_string);
|
||||
|
||||
char *result = fgets(*out_string, max_buffer, stdin);
|
||||
check(result != NULL, "Input error.");
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
if(*out_string) free(*out_string);
|
||||
*out_string = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int read_int(int *out_int)
|
||||
{
|
||||
char *input = NULL;
|
||||
int rc = read_string(&input, MAX_DATA);
|
||||
check(rc == 0, "Failed to read number.");
|
||||
|
||||
*out_int = atoi(input);
|
||||
|
||||
free(input);
|
||||
return 0;
|
||||
|
||||
error:
|
||||
if(input) free(input);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int read_scan(const char *fmt, ...)
|
||||
{
|
||||
int i = 0;
|
||||
int rc = 0;
|
||||
int *out_int = NULL;
|
||||
char *out_char = NULL;
|
||||
char **out_string = NULL;
|
||||
int max_buffer = 0;
|
||||
|
||||
va_list argp;
|
||||
va_start(argp, fmt);
|
||||
|
||||
for(i = 0; fmt[i] != '\0'; i++) {
|
||||
if(fmt[i] == '%') {
|
||||
i++;
|
||||
switch(fmt[i]) {
|
||||
case '\0':
|
||||
sentinel("Invalid format, you ended with %%.");
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
out_int = va_arg(argp, int *);
|
||||
rc = read_int(out_int);
|
||||
check(rc == 0, "Failed to read int.");
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
out_char = va_arg(argp, char *);
|
||||
*out_char = fgetc(stdin);
|
||||
break;
|
||||
|
||||
case 's':
|
||||
max_buffer = va_arg(argp, int);
|
||||
out_string = va_arg(argp, char **);
|
||||
rc = read_string(out_string, max_buffer);
|
||||
check(rc == 0, "Failed to read string.");
|
||||
break;
|
||||
|
||||
default:
|
||||
sentinel("Invalid format.");
|
||||
|
||||
}
|
||||
} else {
|
||||
fgetc(stdin);
|
||||
}
|
||||
|
||||
check(!feof(stdin) && !ferror(stdin), "Input error.");
|
||||
}
|
||||
|
||||
va_end(argp);
|
||||
return 0;
|
||||
|
||||
error:
|
||||
va_end(argp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char *first_name = NULL;
|
||||
char initial = ' ';
|
||||
char *last_name = NULL;
|
||||
int age = 0;
|
||||
|
||||
printf("What's your first name? ");
|
||||
int rc = read_scan("%s", MAX_DATA, &first_name);
|
||||
check(rc == 0, "Failed first name.");
|
||||
|
||||
printf("What's your initial? ");
|
||||
rc = read_scan("%c\n", &initial);
|
||||
check(rc == 0, "Failed initial.");
|
||||
|
||||
printf("What's your last name? ");
|
||||
rc = read_scan("%s", MAX_DATA, &last_name);
|
||||
check(rc == 0, "Failed last name.");
|
||||
|
||||
printf("How old are you? ");
|
||||
rc = read_scan("%d", &age);
|
||||
|
||||
printf("---- RESULTS ----\n");
|
||||
printf("First Name: %s", first_name);
|
||||
printf("Initial: '%c'\n", initial);
|
||||
printf("Last Name: %s", last_name);
|
||||
printf("Age: %d\n", age);
|
||||
|
||||
free(first_name);
|
||||
free(last_name);
|
||||
return 0;
|
||||
error:
|
||||
return -1;
|
||||
}
|
74
oldstuff/lcthw-remnants-2/ex27.c
Normal file
74
oldstuff/lcthw-remnants-2/ex27.c
Normal file
@@ -0,0 +1,74 @@
|
||||
#undef NDEBUG
|
||||
#include "dbg.h"
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
/*
|
||||
* naive copy that assumes all inputs are always valid
|
||||
* taken from K&R C and cleaned up a bit;
|
||||
*/
|
||||
void copy(char to[], char from[])
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
// while loop will not end if from isn't '\0' terminated
|
||||
while((to[i] = from[i]) != '\0') {
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* A safer version that checks for many common errors using the
|
||||
* length of each string to control the loops and termination.
|
||||
*/
|
||||
int safercopy(int from_len, char *from, int to_len, char *to)
|
||||
{
|
||||
assert(from != NULL && to != NULL && "from and to can't be NULL");
|
||||
int i = 0;
|
||||
int max = from_len > to_len - 1 ? to_len - 1 : from_len;
|
||||
|
||||
// to_len must have at least 1 byte
|
||||
if(from_len < 0 || to_len <= 0) return -1;
|
||||
|
||||
for(i = 0; i < max; i++) {
|
||||
to[i] = from[i];
|
||||
}
|
||||
|
||||
to[to_len - 1] = '\0';
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
// careful to understand why we can get these sizes
|
||||
char from[] = "0123456789";
|
||||
int from_len = sizeof(from);
|
||||
|
||||
// notice that it's 7 chars + \0
|
||||
char to[] = "0123456";
|
||||
int to_len = sizeof(to);
|
||||
|
||||
debug("Copying '%s':%d to '%s':%d", from, from_len, to, to_len);
|
||||
|
||||
int rc = safercopy(from_len, from, to_len, to);
|
||||
check(rc > 0, "Failed to safercopy.");
|
||||
check(to[to_len - 1] == '\0', "String not terminated.");
|
||||
|
||||
debug("Result is '%s':%d", to, to_len);
|
||||
|
||||
// now try to break it
|
||||
rc = safercopy(from_len * -1, from, to_len, to);
|
||||
check(rc == -1, "safercopy should fail #1");
|
||||
check(to[to_len - 1] == '\0', "String not terminated.");
|
||||
|
||||
rc = safercopy(from_len, from, 0, to);
|
||||
check(rc == -1, "safercopy should fail #2");
|
||||
check(to[to_len - 1] == '\0', "String not terminated.");
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
return 1;
|
||||
}
|
1
oldstuff/lcthw-remnants-2/ex29/.gitignore
vendored
Normal file
1
oldstuff/lcthw-remnants-2/ex29/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
tests/your_library_tests
|
0
oldstuff/lcthw-remnants-2/ex29/LICENSE
Normal file
0
oldstuff/lcthw-remnants-2/ex29/LICENSE
Normal file
59
oldstuff/lcthw-remnants-2/ex29/Makefile
Normal file
59
oldstuff/lcthw-remnants-2/ex29/Makefile
Normal file
@@ -0,0 +1,59 @@
|
||||
CFLAGS = -g -O2 -Wall -Wextra -Isrc -Lbuild -rdynamic -DNDEBUG $(OPTFLAGS)
|
||||
LDLIBS = -ldl $(OPTLIBS)
|
||||
|
||||
PREFIX ?= /usr/local
|
||||
|
||||
SOURCES = $(wildcard src/**/*.c src/*.c)
|
||||
OBJECTS = $(patsubst %.c,%.o,$(SOURCES))
|
||||
|
||||
TEST_SRC = $(wildcard tests/*_tests.c)
|
||||
TESTS = $(patsubst %.c,%,$(TEST_SRC))
|
||||
|
||||
LIBNAME = ex29
|
||||
TARGET = build/lib$(LIBNAME).a
|
||||
SO_TARGET = $(patsubst %.a,%.so,$(TARGET))
|
||||
|
||||
# The Target Build
|
||||
all: $(TARGET) $(SO_TARGET) tests
|
||||
|
||||
dev: CFLAGS = -g -Wall -Isrc -Wall -Wextra $(OPTFLAGS)
|
||||
dev: all
|
||||
|
||||
$(TARGET): CFLAGS += -fPIC
|
||||
$(TARGET): build $(OBJECTS)
|
||||
$(AR) rcs $@ $(OBJECTS)
|
||||
ranlib $@
|
||||
|
||||
$(SO_TARGET): $(TARGET) $(OBJECTS)
|
||||
$(CC) -shared -o $@ $(OBJECTS)
|
||||
|
||||
build:
|
||||
@mkdir -p build
|
||||
@mkdir -p bin
|
||||
|
||||
# The Unit Tests
|
||||
.PHONY: tests
|
||||
tests: LDLIBS += -l$(LIBNAME)
|
||||
tests: $(TESTS)
|
||||
sh ./tests/runtests.sh
|
||||
|
||||
valgrind:
|
||||
VALGRIND="valgrind --log-file=/tmp/valgrind-%p.log" $(MAKE)
|
||||
|
||||
# The Cleaner
|
||||
clean:
|
||||
rm -rf build $(OBJECTS) $(TESTS)
|
||||
rm -f tests/tests.log
|
||||
find . -name "*.gc*" -exec rm {} \;
|
||||
rm -rf `find . -name "*.dSYM" -print`
|
||||
|
||||
# The Install
|
||||
install: all
|
||||
install -d $(DESTDIR)/$(PREFIX)/lib/
|
||||
install $(TARGET) $(DESTDIR)/$(PREFIX)/lib/
|
||||
|
||||
# The Checker
|
||||
BADFUNCS='[^_.>a-zA-Z0-9](str(n?cpy|n?cat|xfrm|n?dup|str|pbrk|tok|_)|stpn?cpy|a?sn?printf|byte_)'
|
||||
check:
|
||||
@echo Files with potentially dangerous functions
|
||||
@egrep $(BADFUNCS) $(SOURCES) || true
|
0
oldstuff/lcthw-remnants-2/ex29/README.md
Normal file
0
oldstuff/lcthw-remnants-2/ex29/README.md
Normal file
30
oldstuff/lcthw-remnants-2/ex29/src/dbg.h
Normal file
30
oldstuff/lcthw-remnants-2/ex29/src/dbg.h
Normal file
@@ -0,0 +1,30 @@
|
||||
#ifndef __dbg_h__
|
||||
#define __dbg_h__
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef NDEBUG
|
||||
#define debug(M, ...)
|
||||
#else
|
||||
#define debug(M, ...) fprintf(stderr, "DEBUG %s:%d:%s: " M "\n", __FILE__, __LINE__, __func__, ##__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#define clean_errno() (errno == 0 ? "None" : strerror(errno))
|
||||
|
||||
#define log_err(M, ...) fprintf(stderr, "[ERROR] (%s:%d:%s: errno: %s) " M "\n", __FILE__, __LINE__, __func__, clean_errno(), ##__VA_ARGS__)
|
||||
|
||||
#define log_warn(M, ...) fprintf(stderr, "[WARN] (%s:%d:%s: errno: %s) " M "\n", __FILE__, __LINE__, __func__, clean_errno(), ##__VA_ARGS__)
|
||||
|
||||
#define log_info(M, ...) fprintf(stderr, "[INFO] (%s:%d:%s) " M "\n", __FILE__, __LINE__, __func__, ##__VA_ARGS__)
|
||||
|
||||
#define check(A, M, ...) if(!(A)) { log_err(M, ##__VA_ARGS__); errno=0; goto error; }
|
||||
|
||||
#define sentinel(M, ...) { log_err(M, ##__VA_ARGS__); errno=0; goto error; }
|
||||
|
||||
#define check_mem(A) check((A), "Out of memory.")
|
||||
|
||||
#define check_debug(A, M, ...) if(!(A)) { debug(M, ##__VA_ARGS__); errno=0; goto error; }
|
||||
|
||||
#endif
|
43
oldstuff/lcthw-remnants-2/ex29/src/ex29.c
Normal file
43
oldstuff/lcthw-remnants-2/ex29/src/ex29.c
Normal file
@@ -0,0 +1,43 @@
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include "dbg.h"
|
||||
|
||||
|
||||
int print_a_message(const char *msg)
|
||||
{
|
||||
printf("A STRING: %s\n", msg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int uppercase(const char *msg, int count)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
for(i = 0; i < count; i++) {
|
||||
printf("%c", toupper(msg[i]));
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int lowercase(const char *msg, int count)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
for(i = 0; i < count; i++) {
|
||||
printf("%c", tolower(msg[i]));
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fail_on_purpose(const char *msg)
|
||||
{
|
||||
return 1;
|
||||
}
|
65
oldstuff/lcthw-remnants-2/ex29/tests/ex29_tests.c
Normal file
65
oldstuff/lcthw-remnants-2/ex29/tests/ex29_tests.c
Normal file
@@ -0,0 +1,65 @@
|
||||
#include "minunit.h"
|
||||
#include <dlfcn.h>
|
||||
|
||||
typedef int (*lib_function)(const char *data, int count);
|
||||
char *lib_file = "build/libex29.so";
|
||||
void *lib = NULL;
|
||||
|
||||
int check_function(const char *func_to_run, const char *data, int expected)
|
||||
{
|
||||
lib_function func = dlsym(lib, func_to_run);
|
||||
check(func != NULL, "Did not find %s function in the library %s: %s", func_to_run, lib_file, dlerror());
|
||||
|
||||
int rc = func(data, (int)strlen(data));
|
||||
check(rc == expected, "Function %s return %d for data: %s", func_to_run, rc, data);
|
||||
|
||||
return 1;
|
||||
error:
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *test_dlopen()
|
||||
{
|
||||
lib = dlopen(lib_file, RTLD_NOW);
|
||||
mu_assert(lib != NULL, "Failed to open the library to test.");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *test_functions()
|
||||
{
|
||||
mu_assert(check_function("print_a_message", "Hello", 0), "print_a_message failed.");
|
||||
mu_assert(check_function("uppercase", "Hello", 0), "uppercase failed.");
|
||||
mu_assert(check_function("lowercase", "Hello", 0), "lowercase failed.");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *test_failures()
|
||||
{
|
||||
mu_assert(check_function("fail_on_purpose", "Hello", 1), "fail_on_purpose should fail.");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *test_dlclose()
|
||||
{
|
||||
int rc = dlclose(lib);
|
||||
mu_assert(rc == 0, "Failed to close lib.");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *all_tests()
|
||||
{
|
||||
mu_suite_start();
|
||||
|
||||
mu_run_test(test_dlopen);
|
||||
mu_run_test(test_functions);
|
||||
mu_run_test(test_failures);
|
||||
mu_run_test(test_dlclose);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
RUN_TESTS(all_tests);
|
38
oldstuff/lcthw-remnants-2/ex29/tests/minunit.h
Normal file
38
oldstuff/lcthw-remnants-2/ex29/tests/minunit.h
Normal file
@@ -0,0 +1,38 @@
|
||||
#undef DNDEBUG
|
||||
#ifndef _minunit_h
|
||||
#define _minunit_h
|
||||
|
||||
#include <stdio.h>
|
||||
#include <dbg.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define mu_suite_start() char *message = NULL
|
||||
|
||||
#define mu_assert(test, message) if (!(test)) {\
|
||||
log_err(message); return message;\
|
||||
}\
|
||||
assertions_made++;
|
||||
#define mu_run_test(test) debug("\n-----%s", " " #test); \
|
||||
message = test(); tests_run++; if (message) return message;
|
||||
|
||||
#define RUN_TESTS(name) int main(int argc, char *argv[]) {\
|
||||
argc = argc; \
|
||||
argv = argv; \
|
||||
debug("----- RUNNING: %s", argv[0]);\
|
||||
printf("----\nRUNNING: %s\n", argv[0]);\
|
||||
char *result = name();\
|
||||
if (result != 0) {\
|
||||
printf("FAILED: %s\n", result);\
|
||||
}\
|
||||
else {\
|
||||
printf("ALL TESTS PASSED\n");\
|
||||
}\
|
||||
printf("Tests run: %d\n", tests_run);\
|
||||
printf("Assertions made: %d\n", assertions_made);\
|
||||
exit(result != 0);\
|
||||
}
|
||||
|
||||
int tests_run;
|
||||
int assertions_made;
|
||||
|
||||
#endif
|
19
oldstuff/lcthw-remnants-2/ex29/tests/runtests.sh
Normal file
19
oldstuff/lcthw-remnants-2/ex29/tests/runtests.sh
Normal file
@@ -0,0 +1,19 @@
|
||||
echo "Running unit tests:"
|
||||
|
||||
for i in tests/*_tests
|
||||
do
|
||||
if test -f $i
|
||||
then
|
||||
if $VALGRIND ./$i 2>> tests/tests.log
|
||||
then
|
||||
echo $i PASS
|
||||
else
|
||||
echo "ERROR in test $i: here's tests/tests.log"
|
||||
echo "------"
|
||||
tail tests/tests.log
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
echo ""
|
12
oldstuff/lcthw-remnants-2/ex3.c
Normal file
12
oldstuff/lcthw-remnants-2/ex3.c
Normal file
@@ -0,0 +1,12 @@
|
||||
#include <stdio.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
int age = 10;
|
||||
int height = 72;
|
||||
|
||||
printf("I am %d years old.\n", age);
|
||||
printf("I am %d inches tall.\n", height);
|
||||
|
||||
return 0;
|
||||
}
|
12
oldstuff/lcthw-remnants-2/ex31.c
Normal file
12
oldstuff/lcthw-remnants-2/ex31.c
Normal file
@@ -0,0 +1,12 @@
|
||||
#include <unistd.h>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
while(i < 100) {
|
||||
usleep(3000);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
57
oldstuff/lcthw-remnants-2/ex35.c
Normal file
57
oldstuff/lcthw-remnants-2/ex35.c
Normal file
@@ -0,0 +1,57 @@
|
||||
#include <stdio.h>
|
||||
|
||||
typedef enum {
|
||||
TYPE_INT,
|
||||
TYPE_FLOAT,
|
||||
TYPE_STRING,
|
||||
} VariantType;
|
||||
|
||||
struct Variant {
|
||||
VariantType type;
|
||||
union {
|
||||
int as_integer;
|
||||
float as_float;
|
||||
char *as_string;
|
||||
} data;
|
||||
};
|
||||
|
||||
typedef struct Variant Variant;
|
||||
|
||||
void Variant_print(Variant *var)
|
||||
{
|
||||
switch(var->type) {
|
||||
case TYPE_INT:
|
||||
printf("INT: %d\n", var->data.as_integer);
|
||||
break;
|
||||
case TYPE_FLOAT:
|
||||
printf("FLOAT: %f\n", var->data.as_float);
|
||||
break;
|
||||
case TYPE_STRING:
|
||||
printf("STRING: %s\n", var->data.as_string);
|
||||
break;
|
||||
default:
|
||||
printf("UNKNOWN TYPE: %d", var->type);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
Variant a_int = {.type = TYPE_INT, .data.as_integer = 100};
|
||||
Variant a_float = {.type = TYPE_FLOAT, .data.as_float = 100.34};
|
||||
Variant a_string = {.type = TYPE_STRING, .data.as_string = "YO DUDE!"};
|
||||
|
||||
Variant_print(&a_int);
|
||||
Variant_print(&a_float);
|
||||
Variant_print(&a_string);
|
||||
|
||||
// here's how you access them
|
||||
a_int.data.as_integer = 200;
|
||||
a_float.data.as_float = 2.345;
|
||||
a_string.data.as_string = "Hi there.";
|
||||
|
||||
Variant_print(&a_int);
|
||||
Variant_print(&a_float);
|
||||
Variant_print(&a_string);
|
||||
|
||||
return 0;
|
||||
}
|
12
oldstuff/lcthw-remnants-2/ex4.c
Normal file
12
oldstuff/lcthw-remnants-2/ex4.c
Normal file
@@ -0,0 +1,12 @@
|
||||
#include <stdio.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
int age = 10;
|
||||
int height = 72;
|
||||
|
||||
printf("I am %d years old.\n", age);
|
||||
printf("I am %d inches tall.\n", height);
|
||||
|
||||
return 0;
|
||||
}
|
12
oldstuff/lcthw-remnants-2/ex5.c
Normal file
12
oldstuff/lcthw-remnants-2/ex5.c
Normal file
@@ -0,0 +1,12 @@
|
||||
#include <stdio.h>
|
||||
|
||||
/* This is a comment. */
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int distance = 100;
|
||||
|
||||
// this is also a comment
|
||||
printf("You are %d miles away.\n", distance);
|
||||
|
||||
return 0;
|
||||
}
|
22
oldstuff/lcthw-remnants-2/ex6.c
Normal file
22
oldstuff/lcthw-remnants-2/ex6.c
Normal file
@@ -0,0 +1,22 @@
|
||||
#include <stdio.h>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int distance = 100;
|
||||
float power = 2.345f;
|
||||
double super_power = 56789.4532;
|
||||
char initial = 'A';
|
||||
char first_name[] = "Zed";
|
||||
char last_name[] = "Shaw";
|
||||
|
||||
printf("You are %d miles away.\n", distance);
|
||||
printf("You have %f levels of power.\n", power);
|
||||
printf("You have %f awesome super powers.\n", super_power);
|
||||
printf("I have na initial %c.\n", initial);
|
||||
printf("I have a first name %s.\n", first_name);
|
||||
printf("I have a last name %s.\n", last_name);
|
||||
printf("My whole name is %s %c. %s.\n",
|
||||
first_name, initial, last_name);
|
||||
|
||||
return 0;
|
||||
}
|
30
oldstuff/lcthw-remnants-2/ex7.c
Normal file
30
oldstuff/lcthw-remnants-2/ex7.c
Normal file
@@ -0,0 +1,30 @@
|
||||
#include <stdio.h>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int bugs = 100;
|
||||
double bug_rate = 1.2;
|
||||
|
||||
printf("You have %d bugs at the imaginary rate of %f.\n",
|
||||
bugs, bug_rate);
|
||||
|
||||
long universe_of_defects = 1L * 1024L * 1024L * 1024L;
|
||||
printf("The entire universe has %ld bugs.\n",
|
||||
universe_of_defects);
|
||||
|
||||
double expected_bugs = bugs * bug_rate;
|
||||
printf("You are expected to have %f bugs.\n",
|
||||
expected_bugs);
|
||||
|
||||
double part_of_universe = expected_bugs / universe_of_defects;
|
||||
printf("That is only a %e portion of the universe.\n",
|
||||
part_of_universe);
|
||||
|
||||
// this makes no sense, just a demo of something weird
|
||||
char nul_byte = '\0';
|
||||
int care_percentage = bugs * nul_byte;
|
||||
printf("Which means you should care %d%%.\n",
|
||||
care_percentage);
|
||||
|
||||
return 0;
|
||||
}
|
36
oldstuff/lcthw-remnants-2/ex8.c
Normal file
36
oldstuff/lcthw-remnants-2/ex8.c
Normal file
@@ -0,0 +1,36 @@
|
||||
#include <stdio.h>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int areas[] = {10, 12, 13, 14, 20};
|
||||
char name[] = "Zed";
|
||||
char full_name[] = {
|
||||
'Z', 'e', 'd',
|
||||
' ', 'A', '.', ' ',
|
||||
'S', 'h', 'a', 'w', '\0'
|
||||
};
|
||||
|
||||
// WARNING: On some systems you may have to change the
|
||||
// %ld in this code to a %u since it will use unsigned ints
|
||||
printf("The size of an int: %ld\n", sizeof(int));
|
||||
printf("The size of areas (int[]): %ld\n",
|
||||
sizeof(areas));
|
||||
printf("The first area is %d, the 2nd %d.\n",
|
||||
areas[0], areas[1]);
|
||||
|
||||
printf("The size of a char: %ld\n", sizeof(char));
|
||||
printf("The size of name (char[]): %ld\n",
|
||||
sizeof(name));
|
||||
printf("The number of chars: %ld\n",
|
||||
sizeof(name) / sizeof(char));
|
||||
|
||||
printf("The size of full_name (char[]): %ld\n",
|
||||
sizeof(full_name));
|
||||
printf("The number of chars: %ld\n",
|
||||
sizeof(full_name) / sizeof(char));
|
||||
|
||||
printf("name=\"%s\" and full_name=\"%s\"\n",
|
||||
name, full_name);
|
||||
|
||||
return 0;
|
||||
}
|
55
oldstuff/lcthw-remnants-2/ex9-ec.c
Normal file
55
oldstuff/lcthw-remnants-2/ex9-ec.c
Normal file
@@ -0,0 +1,55 @@
|
||||
#include <stdio.h>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int numbers[4] = {0};
|
||||
char name[4] = {'a'};
|
||||
|
||||
// first, print them out raw
|
||||
printf("numbers: %d %d %d %d\n",
|
||||
numbers[0], numbers[1],
|
||||
numbers[2], numbers[3]);
|
||||
|
||||
printf("name each: %c %c %c %c\n",
|
||||
name[0], name[1],
|
||||
name[2], name[3]);
|
||||
|
||||
printf("name: %s\n", name);
|
||||
|
||||
// setup the numbers
|
||||
numbers[0] = 1;
|
||||
numbers[1] = 2;
|
||||
numbers[2] = 3;
|
||||
numbers[3] = 4;
|
||||
|
||||
// setup the name
|
||||
name[0] = 'Z';
|
||||
name[1] = 'e';
|
||||
name[2] = 'd';
|
||||
name[3] = '\0';
|
||||
|
||||
// then print them out initialized
|
||||
printf("numbers: %d %d %d %d\n",
|
||||
numbers[0], numbers[1],
|
||||
numbers[2], numbers[3]);
|
||||
|
||||
printf("name each: %c %c %c %c\n",
|
||||
name[0], name[1],
|
||||
name[2], name[3]);
|
||||
|
||||
// print the name like a string
|
||||
printf("name: %s\n", name);
|
||||
|
||||
// another way to use name;
|
||||
char *another = "Zed";
|
||||
|
||||
printf("another: %s\n", another);
|
||||
printf("another each: %c %c %c %c\n",
|
||||
another[0], another[1],
|
||||
another[2], another[3]);
|
||||
|
||||
printf("name length: %ld\n", sizeof(name));
|
||||
printf("name as int: %d\n", (int)(*name));
|
||||
|
||||
return 0;
|
||||
}
|
52
oldstuff/lcthw-remnants-2/ex9.c
Normal file
52
oldstuff/lcthw-remnants-2/ex9.c
Normal file
@@ -0,0 +1,52 @@
|
||||
#include <stdio.h>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int numbers[4] = {0};
|
||||
char name[4] = {'a'};
|
||||
|
||||
// first, print them out raw
|
||||
printf("numbers: %d %d %d %d\n",
|
||||
numbers[0], numbers[1],
|
||||
numbers[2], numbers[3]);
|
||||
|
||||
printf("name each: %c %c %c %c\n",
|
||||
name[0], name[1],
|
||||
name[2], name[3]);
|
||||
|
||||
printf("name: %s\n", name);
|
||||
|
||||
// setup the numbers
|
||||
numbers[0] = 1;
|
||||
numbers[1] = 2;
|
||||
numbers[2] = 3;
|
||||
numbers[3] = 4;
|
||||
|
||||
// setup the name
|
||||
name[0] = 'Z';
|
||||
name[1] = 'e';
|
||||
name[2] = 'd';
|
||||
name[3] = '\0';
|
||||
|
||||
// then print them out initialized
|
||||
printf("numbers: %d %d %d %d\n",
|
||||
numbers[0], numbers[1],
|
||||
numbers[2], numbers[3]);
|
||||
|
||||
printf("name each: %c %c %c %c\n",
|
||||
name[0], name[1],
|
||||
name[2], name[3]);
|
||||
|
||||
// print the name like a string
|
||||
printf("name: %s\n", name);
|
||||
|
||||
// another way to use name;
|
||||
char *another = "Zed";
|
||||
|
||||
printf("another: %s\n", another);
|
||||
printf("another each: %c %c %c %c\n",
|
||||
another[0], another[1],
|
||||
another[2], another[3]);
|
||||
|
||||
return 0;
|
||||
}
|
41
oldstuff/lcthw-remnants-2/install-apr
Executable file
41
oldstuff/lcthw-remnants-2/install-apr
Executable file
@@ -0,0 +1,41 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
# go somewhere safe
|
||||
cd /tmp
|
||||
|
||||
# get the source to base APR 1.4.6
|
||||
curl -L -O http://archive.apache.org/dist/apr/apr-1.4.6.tar.gz
|
||||
|
||||
# extract it and go into the source
|
||||
tar -xzvf apr-1.4.6.tar.gz
|
||||
cd apr-1.4.6
|
||||
|
||||
# configure, make, make install
|
||||
./configure
|
||||
make
|
||||
sudo make install
|
||||
|
||||
# reset and cleanup
|
||||
cd /tmp
|
||||
rm -rf apr-1.4.6 apr-1.4.6.tar.gz
|
||||
|
||||
# do the same with apr-util
|
||||
curl -L -O http://archive.apache.org/dist/apr/apr-util-1.4.1.tar.gz
|
||||
|
||||
# extract
|
||||
tar -xzvf apr-util-1.4.1.tar.gz
|
||||
cd apr-util-1.4.1
|
||||
|
||||
# configure, make, make install
|
||||
./configure --with-apr=/usr/local/apr
|
||||
# you need that extra parameter to configure because
|
||||
# apr-util can't really find it because...who knows.
|
||||
|
||||
make
|
||||
sudo make install
|
||||
|
||||
#cleanup
|
||||
cd /tmp
|
||||
rm -rf apr-util-1.4.1* apr-1.4.6*
|
5
oldstuff/lcthw-remnants-2/liblcthw/.gitignore
vendored
Normal file
5
oldstuff/lcthw-remnants-2/liblcthw/.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
tests/runtests
|
||||
tests/*_tests
|
||||
tests/**/*_tests
|
||||
bstrlib.c
|
||||
bstrlib.h
|
21
oldstuff/lcthw-remnants-2/liblcthw/LICENSE
Normal file
21
oldstuff/lcthw-remnants-2/liblcthw/LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
Copyright (C) 2016 Dan Buch
|
||||
|
||||
MIT License
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
76
oldstuff/lcthw-remnants-2/liblcthw/Makefile
Normal file
76
oldstuff/lcthw-remnants-2/liblcthw/Makefile
Normal file
@@ -0,0 +1,76 @@
|
||||
BSTRLIB_BASE_URL ?= https://raw.githubusercontent.com/websnarf/bstrlib/208b1f2a4dfc96b806ed499bd1909e87ec15981d
|
||||
CFLAGS = -g -O2 -Wall -Wextra -Isrc -Lbuild -rdynamic -DNDEBUG $(OPTFLAGS)
|
||||
LDLIBS = -ldl $(OPTLIBS)
|
||||
|
||||
PREFIX ?= /usr/local
|
||||
|
||||
FIND ?= find
|
||||
CD ?= cd
|
||||
PATCH ?= patch
|
||||
INSTALL ?= install
|
||||
MKDIR ?= mkdir -p
|
||||
CURL ?= curl -sSL
|
||||
RANLIB ?= ranlib
|
||||
RUNTESTS ?= ./tests/runtests
|
||||
|
||||
SOURCES = $(wildcard src/**/*.c src/*.c)
|
||||
OBJECTS = $(patsubst %.c,%.o,$(SOURCES))
|
||||
|
||||
TEST_SRC = $(wildcard tests/**/*_tests.c tests/*_tests.c)
|
||||
TESTS = $(patsubst %.c,%,$(TEST_SRC))
|
||||
|
||||
LIBNAME = lcthw
|
||||
TARGET = build/lib$(LIBNAME).a
|
||||
SO_TARGET = $(patsubst %.a,%.so,$(TARGET))
|
||||
|
||||
all: $(TARGET) $(SO_TARGET) tests
|
||||
|
||||
dev: CFLAGS = -g -Wall -Isrc -Wall -Wextra $(OPTFLAGS)
|
||||
dev: all
|
||||
|
||||
$(TARGET): CFLAGS += -fPIC
|
||||
$(TARGET): build $(OBJECTS)
|
||||
$(AR) rcs $@ $(OBJECTS)
|
||||
$(RANLIB) $@
|
||||
|
||||
$(SO_TARGET): $(TARGET) $(OBJECTS)
|
||||
$(CC) -shared -o $@ $(OBJECTS)
|
||||
|
||||
build: bin src/lcthw/bstrlib.c src/lcthw/bstrlib.h
|
||||
@$(MKDIR) $@
|
||||
|
||||
bin:
|
||||
@$(MKDIR) $@
|
||||
|
||||
src/lcthw/bstrlib.c: src/lcthw/bstrlib.h
|
||||
$(CURL) -o $@ $(BSTRLIB_BASE_URL)/bstrlib.c
|
||||
$(CD) src/lcthw && $(PATCH) -p1 < bstrlib.patch
|
||||
|
||||
src/lcthw/bstrlib.h:
|
||||
$(CURL) -o $@ $(BSTRLIB_BASE_URL)/bstrlib.h
|
||||
|
||||
.PHONY: tests
|
||||
tests: LDLIBS += -static -l$(LIBNAME) -lbsd
|
||||
tests: $(RUNTESTS) $(TESTS)
|
||||
$(RUNTESTS) ./tests/lcthw
|
||||
|
||||
valgrind:
|
||||
VALGRIND="valgrind --log-file=/tmp/valgrind-%p.log" $(MAKE)
|
||||
|
||||
clean:
|
||||
$(RM) -r build $(OBJECTS) $(TESTS)
|
||||
$(RM) tests/tests.log tests/runtests
|
||||
$(FIND) . -name "*.gc*" -exec rm {} \;
|
||||
$(RM) -r `find . -name "*.dSYM" -print`
|
||||
|
||||
distclean: clean
|
||||
$(RM) src/lcthw/bstrlib.c src/lcthw/bstrlib.h
|
||||
|
||||
install: all
|
||||
$(INSTALL) -d $(DESTDIR)/$(PREFIX)/lib/
|
||||
$(INSTALL) $(TARGET) $(DESTDIR)/$(PREFIX)/lib/
|
||||
|
||||
BADFUNCS='[^_.>a-zA-Z0-9](str(n?cpy|n?cat|xfrm|n?dup|str|pbrk|tok|_)|stpn?cpy|a?sn?printf|byte_)'
|
||||
check:
|
||||
@echo Files with potentially dangerous functions
|
||||
@egrep $(BADFUNCS) $(SOURCES) || true
|
0
oldstuff/lcthw-remnants-2/liblcthw/README.md
Normal file
0
oldstuff/lcthw-remnants-2/liblcthw/README.md
Normal file
12
oldstuff/lcthw-remnants-2/liblcthw/src/lcthw/bstrlib.patch
Normal file
12
oldstuff/lcthw-remnants-2/liblcthw/src/lcthw/bstrlib.patch
Normal file
@@ -0,0 +1,12 @@
|
||||
--- a/bstrlib.c 2016-04-21 12:26:50.000000000 -0400
|
||||
+++ b/bstrlib.c 2016-04-21 12:27:59.000000000 -0400
|
||||
@@ -22,7 +22,8 @@
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
-#include "bstrlib.h"
|
||||
+// PATCH to include adjacent bstrlib.h
|
||||
+#include <lcthw/bstrlib.h>
|
||||
|
||||
/* Optionally include a mechanism for debugging memory */
|
||||
|
116
oldstuff/lcthw-remnants-2/liblcthw/src/lcthw/darray.c
Normal file
116
oldstuff/lcthw-remnants-2/liblcthw/src/lcthw/darray.c
Normal file
@@ -0,0 +1,116 @@
|
||||
#include <lcthw/darray.h>
|
||||
#include <assert.h>
|
||||
|
||||
|
||||
DArray *DArray_create(size_t element_size, size_t initial_max)
|
||||
{
|
||||
DArray *array = malloc(sizeof(DArray));
|
||||
check_mem(array);
|
||||
array->max = initial_max;
|
||||
check(array->max > 0, "You must set an initial_max > 0.");
|
||||
|
||||
array->contents = calloc(initial_max, sizeof(void *));
|
||||
check_mem(array->contents);
|
||||
|
||||
array->end = 0;
|
||||
array->element_size = element_size;
|
||||
array->expand_rate = DEFAULT_EXPAND_RATE;
|
||||
|
||||
return array;
|
||||
|
||||
error:
|
||||
if(array) free(array);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void DArray_clear(DArray *array)
|
||||
{
|
||||
int i = 0;
|
||||
if(array->element_size > 0) {
|
||||
for(i = 0; i < array->max; i++) {
|
||||
if(array->contents[i] != NULL) {
|
||||
free(array->contents[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline int DArray_resize(DArray *array, size_t newsize)
|
||||
{
|
||||
array->max = newsize;
|
||||
check(array->max > 0, "The newsize must be > 0.");
|
||||
|
||||
void *contents = realloc(array->contents, array->max * sizeof(void *));
|
||||
|
||||
check_mem(contents);
|
||||
|
||||
array->contents = contents;
|
||||
|
||||
return 0;
|
||||
error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
int DArray_expand(DArray *array)
|
||||
{
|
||||
size_t old_max = array->max;
|
||||
check(DArray_resize(array, array->max + array->expand_rate) == 0,
|
||||
"Failed to expand array to new size: %d",
|
||||
array->max + (int)array->expand_rate);
|
||||
|
||||
memset(array->contents + old_max, 0, array->expand_rate + 1);
|
||||
return 0;
|
||||
|
||||
error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
int DArray_contract(DArray *array)
|
||||
{
|
||||
int new_size = array->end < (int)array->expand_rate ? (int)array->expand_rate : array->end;
|
||||
|
||||
return DArray_resize(array, new_size + 1);
|
||||
}
|
||||
|
||||
|
||||
void DArray_destroy(DArray *array)
|
||||
{
|
||||
if(array) {
|
||||
if(array->contents) free(array->contents);
|
||||
free(array);
|
||||
}
|
||||
}
|
||||
|
||||
void DArray_clear_destroy(DArray *array)
|
||||
{
|
||||
DArray_clear(array);
|
||||
DArray_destroy(array);
|
||||
}
|
||||
|
||||
int DArray_push(DArray *array, void *el)
|
||||
{
|
||||
array->contents[array->end] = el;
|
||||
array->end++;
|
||||
|
||||
if(DArray_end(array) >= DArray_max(array)) {
|
||||
return DArray_expand(array);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void *DArray_pop(DArray *array)
|
||||
{
|
||||
check(array->end - 1 >= 0, "Attempt to pop from empty array.");
|
||||
|
||||
void *el = DArray_remove(array, array->end - 1);
|
||||
array->end--;
|
||||
|
||||
if(DArray_end(array) > (int)array->expand_rate && DArray_end(array) % array->expand_rate) {
|
||||
DArray_contract(array);
|
||||
}
|
||||
|
||||
return el;
|
||||
error:
|
||||
return NULL;
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user