rdiscountwl 1.0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 5cf4a08fc2c37e30426673510f7b439d449c0259aa7f1e44d29d9bb0ccdb8982
4
+ data.tar.gz: 72f862b4b48d71ce5f5928c5cd26d002b77fb9d48fd1ab30922a807ac79b9481
5
+ SHA512:
6
+ metadata.gz: ee42bb1796afd8e69375f57848787e739ccb8cc1d94d0d7ff859e39c605e1e8765301c42a53080f4f3bd2c5f769475fb543c26c13326baaaf6d9e2fa2c4bf844
7
+ data.tar.gz: 42e679b35f2398656d9521ea69a9d3d84fcccb8db56a8c35d0a94db9287b0446283a57308b01b7fc26d0c42776a8d34eb4704944dcc82ba8542f2034c0260e7f
data/BUILDING ADDED
@@ -0,0 +1,151 @@
1
+ BUILDING rdiscount
2
+ ==================
3
+
4
+ You'll be needing Ruby, rake, and a basic build environment.
5
+
6
+ Build the rdiscount extension for tests and local development:
7
+
8
+ $ rake build
9
+
10
+ Use your rdiscount working copy when running ruby programs:
11
+
12
+ $ export RUBYLIB=~/rdiscount/lib:$RUBYLIB
13
+ $ ruby some-program.rb
14
+
15
+ Gathering changes from an upstream discount clone requires first
16
+ grabbing the discount submodule into the root of the project and then running
17
+ the rake gather task to copy discount source files into the ext/ directory:
18
+
19
+ $ git submodule update --init
20
+ Submodule 'discount' (git://github.com/davidfstr/discount.git) registered for path 'discount'
21
+ Cloning into discount...
22
+ $ cd discount
23
+ $ ./configure.sh
24
+ $ make # ensure it compiles
25
+ $ cd ..
26
+ $ rake gather
27
+ $ rake build
28
+
29
+
30
+ UPGRADING Discount
31
+ ==================
32
+
33
+ The most common maintenance task is upgrading the version of Discount that
34
+ RDiscount is using.
35
+
36
+ Before doing anything, make sure you can build the current (unmodified) version
37
+ of RDiscount. See the section above for details.
38
+
39
+ Update the Discount submodule to the desired version:
40
+
41
+ $ cd discount
42
+ $ git fetch
43
+ $ git checkout v2.0.7.x # insert desired version
44
+ $ cd ..
45
+
46
+ Copy the new Discount sources to the appropriate directories for RDiscount:
47
+
48
+ $ rake gather
49
+
50
+ Update rdiscount.gemspec to include all *.c, *.h, and *.rb files in
51
+ ext. This must be done manually. Here's a quick way to get the full list:
52
+
53
+ $ echo ext/*.c ext/*.h ext/*.rb ext/blocktags ext/VERSION | tr ' ' "\n" | sort
54
+
55
+ (There is an old Rakefile target called "rdiscount.gemspec" that looks like it
56
+ is designed to perform an update of these files, however I haven't tested it.)
57
+
58
+ Build the RDiscount gem. If you get errors related to missing files
59
+ in ext, make sure you updated the gemspec correctly in the previous step.
60
+
61
+ $ gem build rdiscount.gemspec
62
+
63
+ Install this new gem locally. It is recommended that you use RVM to
64
+ create an isolated installation environment. If you get an error after the line
65
+ "Building native extensions", see the troubleshooting section below.
66
+
67
+ $ rvm ruby@rdiscount --create # recommended; requires RVM
68
+ $ gem install rdiscount-*.gem
69
+
70
+ Make sure the gem can be imported:
71
+
72
+ $ ruby -e 'require "rdiscount"'
73
+
74
+ Make sure the tests (still) pass:
75
+
76
+ $ rake test
77
+
78
+ Worked? Swell! The hard part is past.
79
+
80
+ Check the Discount release notes to determine whether it has gained any new
81
+ features that should be exposed through the RDiscount Ruby interface
82
+ (lib/rdiscount.rb), such as new MKD_* flags or configure flags.
83
+ If so, update the Ruby interface.
84
+
85
+ If the ./configure.sh line needs to be changed to support new features,
86
+ you will need to port some #defines from discount/config.h to ext/config.h
87
+ manually to get RDiscount's embedded Discount to use the same configure flags.
88
+
89
+ For new Discount extensions via new MKD_* flags, you will need to update:
90
+
91
+ * lib/rdiscount.rb with new accessors and
92
+ * the rb_rdiscount__get_flags function in ext/rdiscount.c with new
93
+ accessor-to-flag mappings for each new extension.
94
+
95
+ You should also look for RDiscount-specific bugs & feature requests in the
96
+ GitHub tracker and fix a few.
97
+
98
+ If any bugs were fixed or features added be sure to also add new tests!
99
+ And don't forget to rerun the preexisting tests.
100
+
101
+ Update the CHANGELOG.
102
+
103
+ Update rdiscount.gemspec with the new RDiscount version number and date.
104
+ Also update the VERSION constant in lib/rdiscount.rb.
105
+ Push that change as the final commit with a message in the format
106
+ "2.0.7 release".
107
+
108
+ Tag the release commit:
109
+
110
+ $ git tag 2.0.7 # insert desired version
111
+
112
+ Rebuild the gem file and push it to RubyGems.
113
+
114
+ $ gem build rdiscount.gemspec
115
+ $ gem push rdiscount-NEW_VERSION.gem
116
+
117
+ Announce the new release! For releases with new features it is recommended to
118
+ write a full blog post.
119
+
120
+
121
+ Troubleshooting Native Extension Issues
122
+ ---------------------------------------
123
+
124
+ The most likely place where errors will crop up is when you attempt to build
125
+ the C extension. If this happens, you will have to debug manually. Below are
126
+ a few recommended sanity checks:
127
+
128
+ Ensure the Makefile is generated correctly:
129
+
130
+ $ cd ext
131
+ $ ruby extconf.rb
132
+
133
+ Ensure make succeeds:
134
+
135
+ $ make
136
+
137
+ If you get linker errors related to there being duplicate symbols for _main,
138
+ you probably need to update the deploy target of the Rakefile to exclude
139
+ new *.c files from Discount that have a main function.
140
+
141
+ For issues related to config.h or extconf.rb, there was probably some
142
+ change to Discount's configure.sh that broke them. You will probably need
143
+ to update these files in ext/ manually.
144
+
145
+ For other errors, you'll have to investigate yourself. Common error classes:
146
+ * 'ext/configure.sh' fails:
147
+ - Create a patch to the upstream Discount.
148
+ * Some files missing from ext/ that are present in discount/:
149
+ - Update 'rake deploy' target to copy more files.
150
+ * Some files missing when `gem build` is run:
151
+ - Update gemspec to enumerate the correct files in ext/.
data/COPYING ADDED
@@ -0,0 +1,33 @@
1
+ The core Discount C sources are
2
+ Copyright (C) 2007 David Loren Parsons.
3
+
4
+ The Discount Ruby extension sources are
5
+ Copyright (C) 2008 Ryan Tomayko.
6
+
7
+ All rights reserved.
8
+
9
+ Redistribution and use in source and binary forms, with or without
10
+ modification, are permitted provided that the following conditions
11
+ are met:
12
+
13
+ 1. Redistributions of works must retain the original copyright notice,
14
+ this list of conditions and the following disclaimer.
15
+ 2. Redistributions in binary form must reproduce the original copyright
16
+ notice, this list of conditions and the following disclaimer in the
17
+ documentation and/or other materials provided with the distribution.
18
+ 3. Neither my name (David L Parsons) nor the names of contributors to
19
+ this code may be used to endorse or promote products derived
20
+ from this work without specific prior written permission.
21
+
22
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26
+ COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
30
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32
+ ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33
+ POSSIBILITY OF SUCH DAMAGE.
data/README.markdown ADDED
@@ -0,0 +1,73 @@
1
+ Discount Markdown Processor for Ruby
2
+ ====================================
3
+ [![Build Status](https://travis-ci.org/davidfstr/rdiscount.svg?branch=master)](https://travis-ci.org/davidfstr/rdiscount)
4
+ [![Build status](https://ci.appveyor.com/api/projects/status/47i0qxrnvjbg724f/branch/master?svg=true)](https://ci.appveyor.com/project/DavidFoster/rdiscount/branch/master)
5
+
6
+ Discount is an implementation of John Gruber's Markdown markup language in C. It
7
+ implements all of the language described in [the markdown syntax document][1] and
8
+ passes the [Markdown 1.0 test suite][2].
9
+
10
+ CODE: `git clone git://github.com/davidfstr/rdiscount.git`
11
+ HOME: <http://dafoster.net/projects/rdiscount/>
12
+ DOCS: <http://rdoc.info/github/davidfstr/rdiscount/master/RDiscount>
13
+ BUGS: <http://github.com/davidfstr/rdiscount/issues>
14
+
15
+ Discount was developed by [David Loren Parsons][3]. The Ruby extension
16
+ is maintained by [David Foster][4].
17
+
18
+ [1]: http://daringfireball.net/projects/markdown/syntax
19
+ [2]: http://daringfireball.net/projects/downloads/MarkdownTest_1.0.zip
20
+ [3]: http://www.pell.portland.or.us/~orc
21
+ [4]: https://github.com/davidfstr
22
+
23
+ INSTALL, HACKING
24
+ ----------------
25
+
26
+ New releases of RDiscount are published to [RubyGems][]:
27
+
28
+ $ [sudo] gem install rdiscount
29
+
30
+ The RDiscount sources are available via Git:
31
+
32
+ $ git clone git://github.com/davidfstr/rdiscount.git
33
+ $ cd rdiscount
34
+ $ rake --tasks
35
+
36
+ See the file [BUILDING][] for hacking instructions.
37
+
38
+ [RubyGems]: https://rubygems.org/gems/rdiscount
39
+ [BUILDING]: https://github.com/davidfstr/rdiscount/blob/master/BUILDING
40
+
41
+ USAGE
42
+ -----
43
+
44
+ RDiscount implements the basic protocol popularized by RedCloth and adopted
45
+ by BlueCloth:
46
+
47
+ require 'rdiscount'
48
+ markdown = RDiscount.new("Hello World!")
49
+ puts markdown.to_html
50
+
51
+ Additional processing options can be turned on when creating the
52
+ RDiscount object:
53
+
54
+ markdown = RDiscount.new("Hello World!", :smart, :filter_html)
55
+
56
+ Inject RDiscount into your BlueCloth-using code by replacing your bluecloth
57
+ require statements with the following:
58
+
59
+ begin
60
+ require 'rdiscount'
61
+ BlueCloth = RDiscount
62
+ rescue LoadError
63
+ require 'bluecloth'
64
+ end
65
+
66
+ COPYING
67
+ -------
68
+
69
+ Discount is free software; it is released under a BSD-style license
70
+ that allows you to do as you wish with it as long as you don't attempt
71
+ to claim it as your own work. RDiscount adopts Discount's license
72
+ verbatim. See the file `COPYING` for more information.
73
+
data/Rakefile ADDED
@@ -0,0 +1,224 @@
1
+ require 'date'
2
+ require 'rake/clean'
3
+ require 'digest/md5'
4
+
5
+ task :default => :test
6
+
7
+ # ==========================================================
8
+ # Ruby Extension
9
+ # ==========================================================
10
+
11
+ DLEXT = RbConfig::MAKEFILE_CONFIG['DLEXT']
12
+ RUBYDIGEST = Digest::MD5.hexdigest(`ruby --version`)
13
+
14
+ file "ext/ruby-#{RUBYDIGEST}" do |f|
15
+ rm_f FileList["ext/ruby-*"]
16
+ touch f.name
17
+ end
18
+ CLEAN.include "ext/ruby-*"
19
+
20
+ file 'ext/Makefile' => FileList['ext/*.{c,h,rb}', "ext/ruby-#{RUBYDIGEST}"] do
21
+ chdir('ext') { ruby 'extconf.rb' }
22
+ end
23
+ CLEAN.include 'ext/Makefile', 'ext/mkmf.log'
24
+
25
+ file "ext/rdiscount.#{DLEXT}" => FileList["ext/Makefile"] do |f|
26
+ sh 'cd ext && make clean && make && rm -rf conftest.dSYM'
27
+ end
28
+ CLEAN.include 'ext/*.{o,bundle,so,dll}'
29
+
30
+ file "lib/rdiscount.#{DLEXT}" => "ext/rdiscount.#{DLEXT}" do |f|
31
+ cp f.prerequisites, "lib/", :preserve => true
32
+ end
33
+
34
+ desc 'Build the rdiscount extension'
35
+ task :build => "lib/rdiscount.#{DLEXT}"
36
+
37
+ # ==========================================================
38
+ # Manual
39
+ # ==========================================================
40
+
41
+ file 'man/rdiscount.1' => 'man/rdiscount.1.ronn' do
42
+ sh "ronn --manual=RUBY -b man/rdiscount.1.ronn"
43
+ end
44
+ CLOBBER.include 'man/rdiscount.1'
45
+
46
+ desc 'Build manpages'
47
+ task :man => 'man/rdiscount.1'
48
+
49
+ # ==========================================================
50
+ # Testing
51
+ # ==========================================================
52
+
53
+ require 'rake/testtask'
54
+ Rake::TestTask.new('test:unit') do |t|
55
+ t.test_files = FileList['test/*_test.rb']
56
+ t.ruby_opts += ['-rubygems'] if defined? Gem
57
+ end
58
+ task 'test:unit' => [:build]
59
+
60
+ desc 'Run conformance tests (MARKDOWN_TEST_VER=1.0)'
61
+ task 'test:conformance' => [:build] do |t|
62
+ script = "#{pwd}/bin/rdiscount"
63
+ test_version = ENV['MARKDOWN_TEST_VER'] || '1.0.3'
64
+ lib_dir = "#{pwd}/lib"
65
+ chdir("test/MarkdownTest_#{test_version}") do
66
+ result = `RUBYLIB=#{lib_dir} ./MarkdownTest.pl --script='#{script}' --tidy`
67
+ print result
68
+ fail unless result.include? "; 0 failed."
69
+ end
70
+ end
71
+
72
+ desc 'Run version 1.0 conformance suite'
73
+ task 'test:conformance:1.0' => [:build] do |t|
74
+ ENV['MARKDOWN_TEST_VER'] = '1.0'
75
+ Rake::Task['test:conformance'].invoke
76
+ end
77
+
78
+ desc 'Run 1.0.3 conformance suite'
79
+ task 'test:conformance:1.0.3' => [:build] do |t|
80
+ ENV['MARKDOWN_TEST_VER'] = '1.0.3'
81
+ Rake::Task['test:conformance'].invoke
82
+ end
83
+
84
+ desc 'Run unit and conformance tests'
85
+ task :test => %w[test:unit test:conformance]
86
+
87
+ desc 'Run benchmarks'
88
+ task :benchmark => :build do |t|
89
+ $:.unshift 'lib'
90
+ load 'test/benchmark.rb'
91
+ end
92
+
93
+ # ==========================================================
94
+ # Documentation
95
+ # ==========================================================
96
+
97
+ desc 'Generate API documentation'
98
+ task :doc => 'doc/index.html'
99
+
100
+ file 'doc/index.html' => FileList['lib/*.rb'] do |f|
101
+ sh((<<-end).gsub(/\s+/, ' '))
102
+ hanna --charset utf8 --fmt html --inline-source --line-numbers \
103
+ --main RDiscount --op doc --title 'RDiscount API Documentation' \
104
+ #{f.prerequisites.join(' ')}
105
+ end
106
+ end
107
+
108
+ CLEAN.include 'doc'
109
+
110
+ # ==========================================================
111
+ # Update package's Discount sources
112
+ # ==========================================================
113
+
114
+ desc 'Gather required discount sources into extension directory'
115
+ task :gather => 'discount/markdown.h' do |t|
116
+ # Files unique to /ext that should not be overridden
117
+ rdiscount_ext_files = [
118
+ "config.h",
119
+ "extconf.rb",
120
+ "rdiscount.c",
121
+ ]
122
+
123
+ # Files in /discount that have a main function and should not be copied to /ext
124
+ discount_c_files_with_main_function = [
125
+ "main.c",
126
+ "makepage.c",
127
+ "mkd2html.c",
128
+ "theme.c",
129
+ ]
130
+
131
+ # Ensure configure.sh was run
132
+ if not File.exists? 'discount/mkdio.h'
133
+ abort "discount/mkdio.h not found. Did you run ./configure.sh in the discount directory?"
134
+ end
135
+
136
+ # Delete all *.c and *.h files from ext that are not specific to RDiscount.
137
+ Dir.chdir("ext") do
138
+ c_files_to_delete = Dir["*.c"].select { |e| !rdiscount_ext_files.include? e }
139
+ h_files_to_delete = Dir["*.h"].select { |e| !rdiscount_ext_files.include? e }
140
+
141
+ rm (c_files_to_delete + h_files_to_delete),
142
+ :verbose => true
143
+ end
144
+
145
+ # Copy all *.c and *.h files from discount -> ext except those that
146
+ # RDiscount overrides. Also exclude Discount files with main functions.
147
+ Dir.chdir("discount") do
148
+ c_files_to_copy = Dir["*.c"].select { |e|
149
+ (!rdiscount_ext_files.include? e) &&
150
+ (!discount_c_files_with_main_function.include? e)
151
+ }
152
+ h_files_to_copy = Dir["*.h"].select { |e| !rdiscount_ext_files.include? e }
153
+
154
+ cp (c_files_to_copy + h_files_to_copy), '../ext/',
155
+ :preserve => true,
156
+ :verbose => true
157
+ end
158
+
159
+ # Copy special files from discount -> ext
160
+ cp 'discount/blocktags', 'ext/'
161
+ cp 'discount/VERSION', 'ext/'
162
+
163
+ # Copy man page
164
+ cp 'discount/markdown.7', 'man/'
165
+ end
166
+
167
+ file 'discount/markdown.h' do |t|
168
+ abort "The discount submodule is required. See the file BUILDING for getting set up."
169
+ end
170
+
171
+ # PACKAGING =================================================================
172
+
173
+ require 'rubygems'
174
+ $spec = eval(File.read('rdiscount.gemspec'))
175
+
176
+ def package(ext='')
177
+ "pkg/rdiscount-#{$spec.version}" + ext
178
+ end
179
+
180
+ desc 'Build packages'
181
+ task :package => %w[.gem .tar.gz].map {|e| package(e)}
182
+
183
+ desc 'Build and install as local gem'
184
+ task :install => package('.gem') do
185
+ sh "gem install #{package('.gem')}"
186
+ end
187
+
188
+ directory 'pkg/'
189
+
190
+ file package('.gem') => %w[pkg/ rdiscount.gemspec] + $spec.files do |f|
191
+ sh "gem build rdiscount.gemspec"
192
+ mv File.basename(f.name), f.name
193
+ end
194
+
195
+ file package('.tar.gz') => %w[pkg/] + $spec.files do |f|
196
+ sh "git archive --format=tar HEAD | gzip > #{f.name}"
197
+ end
198
+
199
+ # GEMSPEC HELPERS ==========================================================
200
+
201
+ def source_version
202
+ line = File.read('lib/rdiscount.rb')[/^\s*VERSION = .*/]
203
+ line.match(/.*VERSION = '(.*)'/)[1]
204
+ end
205
+
206
+ file 'rdiscount.gemspec' => FileList['Rakefile','lib/rdiscount.rb'] do |f|
207
+ # read spec file and split out manifest section
208
+ spec = File.read(f.name)
209
+ head, manifest, tail = spec.split(" # = MANIFEST =\n")
210
+ head.sub!(/\.version = '.*'/, ".version = '#{source_version}'")
211
+ head.sub!(/\.date = '.*'/, ".date = '#{Date.today.to_s}'")
212
+ # determine file list from git ls-files
213
+ files = `git ls-files`.
214
+ split("\n").
215
+ sort.
216
+ reject{ |file| file =~ /^\./ || file =~ /^test\/MarkdownTest/ }.
217
+ map{ |file| " #{file}" }.
218
+ join("\n")
219
+ # piece file back together and write...
220
+ manifest = " s.files = %w[\n#{files}\n ]\n"
221
+ spec = [head,manifest,tail].join(" # = MANIFEST =\n")
222
+ File.open(f.name, 'w') { |io| io.write(spec) }
223
+ puts "updated #{f.name}"
224
+ end
data/bin/rdiscount ADDED
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env ruby
2
+ # Usage: rdiscount [<file>...]
3
+ # Convert one or more Markdown files to HTML and write to standard output. With
4
+ # no <file> or when <file> is '-', read Markdown source text from standard input.
5
+ if ARGV.include?('--help')
6
+ File.read(__FILE__).split("\n").grep(/^# /).each do |line|
7
+ puts line[2..-1]
8
+ end
9
+ exit 0
10
+ end
11
+
12
+ require 'rdiscount'
13
+ STDOUT.write(RDiscount.new(ARGF.read).to_html)
data/ext/Csio.c ADDED
@@ -0,0 +1,61 @@
1
+ #include <stdio.h>
2
+ #include <string.h>
3
+ #include <stdarg.h>
4
+ #include "cstring.h"
5
+ #include "markdown.h"
6
+ #include "amalloc.h"
7
+
8
+
9
+ /* putc() into a cstring
10
+ */
11
+ void
12
+ Csputc(int c, Cstring *iot)
13
+ {
14
+ EXPAND(*iot) = c;
15
+ }
16
+
17
+
18
+ /* printf() into a cstring
19
+ */
20
+ int
21
+ Csprintf(Cstring *iot, char *fmt, ...)
22
+ {
23
+ va_list ptr;
24
+ int siz=100;
25
+
26
+ do {
27
+ RESERVE(*iot, siz);
28
+ va_start(ptr, fmt);
29
+ siz = vsnprintf(T(*iot)+S(*iot), ALLOCATED(*iot)-S(*iot), fmt, ptr);
30
+ va_end(ptr);
31
+ } while ( siz > (ALLOCATED(*iot)-S(*iot)) );
32
+
33
+ S(*iot) += siz;
34
+ return siz;
35
+ }
36
+
37
+
38
+ /* write() into a cstring
39
+ */
40
+ int
41
+ Cswrite(Cstring *iot, char *bfr, int size)
42
+ {
43
+ RESERVE(*iot, size);
44
+ memcpy(T(*iot)+S(*iot), bfr, size);
45
+ S(*iot) += size;
46
+ return size;
47
+ }
48
+
49
+
50
+ /* reparse() into a cstring
51
+ */
52
+ void
53
+ Csreparse(Cstring *iot, char *buf, int size, int flags)
54
+ {
55
+ MMIOT f;
56
+ ___mkd_initmmiot(&f, 0);
57
+ ___mkd_reparse(buf, size, 0, &f, 0);
58
+ ___mkd_emblock(&f);
59
+ SUFFIX(*iot, T(f.out), S(f.out));
60
+ ___mkd_freemmiot(&f, 0);
61
+ }
data/ext/VERSION ADDED
@@ -0,0 +1 @@
1
+ 2.2.0
data/ext/amalloc.c ADDED
@@ -0,0 +1,135 @@
1
+ /*
2
+ * debugging malloc()/realloc()/calloc()/free() that attempts
3
+ * to keep track of just what's been allocated today.
4
+ */
5
+
6
+ #include <stdio.h>
7
+ #include <stdlib.h>
8
+
9
+ #define MAGIC 0x1f2e3d4c
10
+
11
+ struct alist { int magic, size, index; int *end; struct alist *next, *last; };
12
+
13
+ static struct alist list = { 0, 0, 0, 0 };
14
+
15
+ static int mallocs=0;
16
+ static int reallocs=0;
17
+ static int frees=0;
18
+
19
+ static int index = 0;
20
+
21
+ static void
22
+ die(char *msg, int index)
23
+ {
24
+ fprintf(stderr, msg, index);
25
+ abort();
26
+ }
27
+
28
+
29
+ void *
30
+ acalloc(int count, int size)
31
+ {
32
+ struct alist *ret;
33
+
34
+ if ( size > 1 ) {
35
+ count *= size;
36
+ size = 1;
37
+ }
38
+
39
+ if ( ret = calloc(count + sizeof(struct alist) + sizeof(int), size) ) {
40
+ ret->magic = MAGIC;
41
+ ret->size = size * count;
42
+ ret->index = index ++;
43
+ ret->end = (int*)(count + (char*) (ret + 1));
44
+ *(ret->end) = ~MAGIC;
45
+ if ( list.next ) {
46
+ ret->next = list.next;
47
+ ret->last = &list;
48
+ ret->next->last = ret;
49
+ list.next = ret;
50
+ }
51
+ else {
52
+ ret->last = ret->next = &list;
53
+ list.next = list.last = ret;
54
+ }
55
+ ++mallocs;
56
+ return ret+1;
57
+ }
58
+ return 0;
59
+ }
60
+
61
+
62
+ void*
63
+ amalloc(int size)
64
+ {
65
+ return acalloc(size,1);
66
+ }
67
+
68
+
69
+ void
70
+ afree(void *ptr)
71
+ {
72
+ struct alist *p2 = ((struct alist*)ptr)-1;
73
+
74
+ if ( p2->magic == MAGIC ) {
75
+ if ( ! (p2->end && *(p2->end) == ~MAGIC) )
76
+ die("goddam: corrupted memory block %d in free()!\n", p2->index);
77
+ p2->last->next = p2->next;
78
+ p2->next->last = p2->last;
79
+ ++frees;
80
+ free(p2);
81
+ }
82
+ else
83
+ free(ptr);
84
+ }
85
+
86
+
87
+ void *
88
+ arealloc(void *ptr, int size)
89
+ {
90
+ struct alist *p2 = ((struct alist*)ptr)-1;
91
+ struct alist save;
92
+
93
+ if ( p2->magic == MAGIC ) {
94
+ if ( ! (p2->end && *(p2->end) == ~MAGIC) )
95
+ die("goddam: corrupted memory block %d in realloc()!\n", p2->index);
96
+ save.next = p2->next;
97
+ save.last = p2->last;
98
+ p2 = realloc(p2, sizeof(int) + sizeof(*p2) + size);
99
+
100
+ if ( p2 ) {
101
+ p2->size = size;
102
+ p2->end = (int*)(size + (char*) (p2 + 1));
103
+ *(p2->end) = ~MAGIC;
104
+ p2->next->last = p2;
105
+ p2->last->next = p2;
106
+ ++reallocs;
107
+ return p2+1;
108
+ }
109
+ else {
110
+ save.next->last = save.last;
111
+ save.last->next = save.next;
112
+ return 0;
113
+ }
114
+ }
115
+ return realloc(ptr, size);
116
+ }
117
+
118
+
119
+ void
120
+ adump()
121
+ {
122
+ struct alist *p;
123
+
124
+
125
+ for ( p = list.next; p && (p != &list); p = p->next ) {
126
+ fprintf(stderr, "allocated: %d byte%s\n", p->size, (p->size==1) ? "" : "s");
127
+ fprintf(stderr, " [%.*s]\n", p->size, (char*)(p+1));
128
+ }
129
+
130
+ if ( getenv("AMALLOC_STATISTICS") ) {
131
+ fprintf(stderr, "%d malloc%s\n", mallocs, (mallocs==1)?"":"s");
132
+ fprintf(stderr, "%d realloc%s\n", reallocs, (reallocs==1)?"":"s");
133
+ fprintf(stderr, "%d free%s\n", frees, (frees==1)?"":"s");
134
+ }
135
+ }