From: Han-Wen Nienhuys Date: Thu, 6 Mar 1997 18:16:55 +0000 (+0100) Subject: release: 0.0.39-1 X-Git-Tag: release/0.0.39-1 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=daee8243ff1c66bc714455a2d265ab02f03546ec;p=lilypond.git release: 0.0.39-1 --- diff --git a/.dstreamrc b/.dstreamrc deleted file mode 100644 index 13642e8b39..0000000000 --- a/.dstreamrc +++ /dev/null @@ -1,54 +0,0 @@ -# class name silence? - -My_flex_lexer 1 -yyFlexLexer 1 -PCol 1 -Score_column 1 -Ineq_constrained_qp 1 -Spacing_problem 1 -Colinfo 1 -Mixed_qp 1 -PScore 1 -Idealspacing 1 - -# yydebug -InitParser 1 -Parser 1 -InitDeclarations 1 - -# FlexLexer debug -InitLexer 1 -Lexer 1 - -parse_duration 1 -parse_pitchmod 1 -Col_configuration 1 -Request 0 -Note_req 1 -Rhythmic_req 0 -Rest_req 1 -delete_identifiers 1 -Command 1 -Staff_commands 1 -Stem 1 -Staff 0 -Score 1 -Voice 0 -Voice_element 0 -Input_cursor 1 -Commands_at 1 -Input_command 1 -Time_description 1 -Melodic_req 0 -Midi_walker 0 -Stem_req 1 -Group_change_req 0 -Script_req 1 -Colinfo 1 -Word_wrap 1 -Text_req 1 -Script_def 1 -Text_def 1 -Paperdef 1 -Symtable 1 -Symtables 1 \ No newline at end of file diff --git a/.version b/.version new file mode 100644 index 0000000000..22587f334f --- /dev/null +++ b/.version @@ -0,0 +1,6 @@ +TOPLEVEL_MAJOR_VERSION = 0 +TOPLEVEL_MINOR_VERSION = 0 +TOPLEVEL_PATCH_LEVEL = 39 +# use to send patches, always empty for released version: +TOPLEVEL_MY_PATCH_LEVEL = -1# include separator: "-1" or ".a" +# diff --git a/Documentation/CodingStyle.pod b/Documentation/CodingStyle.pod index 2ccc103080..9bf71c3810 100644 --- a/Documentation/CodingStyle.pod +++ b/Documentation/CodingStyle.pod @@ -16,14 +16,13 @@ in emacs: (add-hook 'c-mode-hook '(lambda ()(setq c-basic-offset 4))) + + (add-hook 'c++-mode-hook '(lambda() (c-set-style "Stroustrup") ) ) -=head2 FILES -The class C is declared in F and -implemented in F. =head2 CLASSES and TYPES: @@ -35,7 +34,7 @@ implemented in F. Class::member() Type Class::member_type_ -the C is a Hungarian notation postfix for C. See below +the C is a Hungarian notation postfix for $C$. See below =head2 COMMENTS @@ -89,7 +88,7 @@ symbols. Staff is the "brains" for PStaff NB: in PCursor (which is part of the library) P stands for PointerCursor -=head2 MEMBERS (2) +=head2 MEMBERS(2) Standard methods: @@ -121,9 +120,9 @@ Notation>. =head2 Hungarian The Hungarian Notation was conceived by or at least got its name from, -the hungarian programmer x. It is a naming convention with the aim to -make code more readable (for fellow programmers) and more accessible -for programmers that are new to a project. +the hungarian programmer Charles Simonyi. It is a naming convention +with the aim to make code more readable (for fellow programmers), and +more accessible for programmers that are new to a project. The essence of the Hungarian Notation is that every identifier has a part which identifies its type (for functions this is the result @@ -210,9 +209,9 @@ with the parts of the names separated by underscores. =over 5 =item C -unsigned cher. (The postfix _by is ambiguous) +unsigned char. (The postfix _by is ambiguous) -=item C +=item C bool =item C @@ -257,7 +256,7 @@ These are precede the prefixes: =item C array -=item C +=item C user built array. =item C @@ -283,19 +282,19 @@ Variable loop: an integer Temporary variable: an unsigned integer =item C -Variable Test: a character +Variable test: a character =item C Variable first_name: a String class object -=item C -Variable first_name: a C array +=item C +Variable last_name: a C array -=item C -Variable Loop: an C that you must delete +=item C +Variable foo: an C that you must delete -=item C -Variable Loop: an C that you must not delete +=item C +Variable bar: an C that you must not delete =back diff --git a/Documentation/Makefile b/Documentation/Makefile index 0dc97f7dbe..e95293e314 100644 --- a/Documentation/Makefile +++ b/Documentation/Makefile @@ -1,30 +1,53 @@ -PODS=README.pod CodingStyle.pod lilygut.pod lilyinput.pod error.pod\ - faq.pod index.pod language.pod -TXTS=$(PODS:.pod=.txt) -MANS=$(PODS:.pod=.1) -HTMLS=$(PODS:.pod=.html) -DISTFILES=$(PODS) Makefile lelie_logo.png make_website - - -default: - $(MAKE) -C .. doc - -doc: $(TXTS) - -dist: - ln $(DISTFILES) $(DDIR)/$(SUBDIR) -clean: - rm -f $(TXTS) $(MANS) - -%.txt: %.1 - groff -man -Tascii $< > $@ - -%.1: %.pod - pod2man --center="LilyPond documentation" --section="0"\ - --release="LilyPond $(MAJVER).$(MINVER).$(PATCHLEVEL)" $< > $@ +# Documentation/Makefile + +# subdir level: +# +depth = .. +# + +# identify module: +# +NAME = Documentation +MAJOR_VERSION = $(TOPLEVEL_MAJOR_VERSION) +MINOR_VERSION = $(TOPLEVEL_MINOR_VERSION) +PATCH_LEVEL = $(TOPLEVEL_PATCH_LEVEL) +# use to send patches, always empty for released version: +MY_PATCH_LEVEL = $(TOPLEVEL_MY_PATCH_LEVEL) +build = ./$(depth)/lily/.build +# + +# generic variables: +# +include ./$(depth)/make/Variables.make +# + +# list of source files: +# +PODFILES = $(shell ls *.pod) +OUTPODFILES = $(patsubst %,$(outdir)/%,$(PODFILES)) +TEXTFILES = $(OUTPODFILES:.pod=.text) +MANFILES = $(OUTPODFILES:.pod=.1) +HTMLFILES = $(OUTPODFILES:.pod=.html) +# + +# list of distribution files: +# +DISTFILES = $(PODFILES) Makefile lelie_logo.png +# + +default: do-doc + +do-doc: $(TEXTFILES) html: $(pod) pod2html htmldist: html - make_website + ./$(bindir)/make_website + +# generic targets and rules: +# +include ./$(depth)/make/Targets.make +include ./$(depth)/make/Rules.make +# + diff --git a/Documentation/README.pod b/Documentation/README.pod index a4dc31770b..96c5ea4dd5 100644 --- a/Documentation/README.pod +++ b/Documentation/README.pod @@ -123,7 +123,7 @@ add F to the search path for input files. =item B<-M,--midi> -Do midi output only. +do midi output only =item B<-d,--debug>, @@ -201,7 +201,7 @@ LilyPond does use a lot of resources. For operation you need the following: =over 5 =item * -A fast computer (a full page of music typically takes 1 minute +a fast computer (a full page of music typically takes 1 minute on my 486/66, using the DEBUG compile. It's lot slower than most MusiXTeX preprocessors) @@ -226,7 +226,7 @@ Do: You probably want to edit Variables.make to tailor the compilation flags. If you're not into debugging C++, then you should go for no -debugging and C<-O2>. +debugging and C<-O2> =head1 AUTHORS @@ -236,11 +236,11 @@ debugging and C<-O2>. Han-Wen Nienhuys , Main author =item * -Jan C. Nieuwenhuizen , Context errors, Lyrics, Midi -output, m2m, bits of FlowerLib, general comments. +Jan Nieuwenhuizen , Context errors, Lyrics, +bits of FlowerLib, general comments. =item * -Mats Bengtsson , bugfixes, testing, criticism, general comments. +Mats Bengtsson , bugfixes, testing, general comments. =back @@ -326,10 +326,8 @@ includes files from the directory F. =head1 SEE ALSO -There are some documentation files in the subdirectory -F, among others: lilygut, lilyinput, error, faq. There -is a rudimentary webpage at the following URL: -http://www.stack.nl/~hanwen/lilypond/index.html +There are some documentation files in the subdirectory F, +among others: lilygut, lilyinput, error, faq, =head1 REMARKS diff --git a/Documentation/faq.pod b/Documentation/faq.pod index 8cb445e23c..79e511498e 100644 --- a/Documentation/faq.pod +++ b/Documentation/faq.pod @@ -6,20 +6,6 @@ FAQ - LilyPond FAQs Some questions that have been answered before. -Q: Gee, I really like MPP, why would I want to switch to LilyPond? - -A: The design of MPP is broken beyond repair: it is very difficult to -enhance MPP, and any working version is (probably) bug-ridden. - -Every once in a while, I have a major attack of hybris, and I go in to -enhance MPP. I usually end up thoroughly frustated within an hour or -so. I concur, it does work but extending MPP is a major pain. - -We will not sacrifice development time on something else than the most -trivial bugfixes. If you insist on using MusiXTeX, then LilyPond is -not for you, and you might try PMX which does also nice output. - - Q: Why are [] around the notes, and () inbetween? A: [] designate beams, a note can only be in one beam at the same @@ -34,13 +20,13 @@ Q: I want a DOS/NT/W95 port. A0: Reconsider. Try Linux. It's fun! A1: Currently (patchlevel 27), LilyPond (and flowerLib) compiles, links -and runs on Windhoos-NT, using the CYGNUS GNU port (release b17.1). +and runs on windhoos-nt, using the cygnus gnu port (release b17.1). I (JCN) only had to make a minor workaround for missing library calls. Have a look at http://www.cygnus.com/gnu-win32. To make LilyPond type -C. (I am not promising to maintain this platform, it is just that +make $OS. (I am not promising to maintain this platform, it is just that when having to use doze, i-m sometimes too lazy to reboot.) -A2: I haven't had time to find a GCC crosscompiler (I g++, mind you) to +A2: I haven't had time to find a GCC crosscompiler (*with* g++, mind you) to DOS/win (in rpm, please :). @@ -48,7 +34,6 @@ Q: Why GPL? A: Yes. - Q: Why shouldn't I put all commands (\clef, \meter) inside the music? A: You should do what you like, but at some time we will enable @@ -68,10 +53,8 @@ simple front end to the complicated internals. Q: Why do I need g++ >= 2.7? A: By using g++ LilyPond is portable to all platforms which support -g++ (there are quite a few, more than platforms which have AT&T CC or -Micro$oft C++). Not having to support other compilers saves us a I -of trouble. You need a version better than 2.7 because LilyPond & -FlowerLib uses: +g++ (there are quite a few). Not having to support other compilers +saves us a *lot* of trouble. LilyPond & FlowerLib uses: =over 6 @@ -98,26 +81,3 @@ named return values =back -Q: Why do I have to tell LilyPond explictly that the lowest-line-note -is "es" if I am using the key of "bes"? - -A: The goal of lilypond (and MPP) was to design a language which -conveys the I message of a piece. That is the reason that it -does not ask you to enter the line on which the note is is. (Or the -"natural" note-name without any "es" or "is" postfix) - -We do realise it is a bit shortsighted of us to assume that any user could -readily read the music he/she is entering. We might extend LilyPond to -allow "programmable" intervals, keys and clefs (and thus give him a -means to build his own scales, custom etc.). - -For now, you can program LilyPond to use custom notenames and do - - notenames { ces_key_notenames } - music { $ % music in the key of ces - ... - $} - notenames { dutch_notenames } % restore default - -as an ad-hoc solution. - diff --git a/Documentation/language.pod b/Documentation/language.pod index c7e9a81bc9..e316fdc14e 100644 --- a/Documentation/language.pod +++ b/Documentation/language.pod @@ -22,12 +22,6 @@ A musical notation that is relatively easy to comprehend to both programmers and non programmers. The final aim is to be able to express what can be expressed in sheet music. -This document is intended to summarise the plans for mudela 2 (mudela -0 being mpp-input, and mudela-1 LilyPond input upto version 0.0.38). -Ideas for any further extensions (mudela 3, read total vapourware) -should be marked as such. - - =over 5 =item * @@ -135,11 +129,6 @@ voices on one staff? We might be able to do without the staff{} construct, but I doubt if it will make things easier. -=head1 DECISIONS - -[none, yet] - - =head1 THOUGHTS =head2 Typing @@ -208,11 +197,7 @@ As simple fix, we might do key declarations: \key{\keybes} -[LOOSE] -We could be even more rabid, and use '\rab' as \bar terminator. - -Just kidding of course... [LOOSE THOUGHT] @@ -313,7 +298,7 @@ Mats is an arduous fan of having the commands inside music. I am not. I see the Mudela music as something which can be plugged into different staffs, transposed, translated in time, copied, quoted, etc. Encouraging "inline" commands would be bad since they hinder this -reuse of mudela-isated music. +reuse of typed music. The way I figure it, the bad part is essentially counting bars/wholes. Maybe we can get rid of it, by reinstalling the "mark" @@ -328,7 +313,6 @@ There is another complication: some symbols (bars) sometimes are linked across staffs. I should first think of a way to do this in LilyPond, before even considering a syntax. -[see also: filtering] =head2 Volta @@ -338,14 +322,11 @@ uhh? The syntax of /, * and : has to be settled, we have - - notes (1, 2, 4, 8 etc), which also can take 1*2/3 to do plets. + - notes (1, 2, 4, 8 etc) - meter 2*4 - plet 2/3 - multiple notes: 3*4 - abbreviations (not implemented) c4/4 or c4*4 - - measure grouping, {2*4 3*4} - - skip - =head2 Filtering @@ -403,6 +384,7 @@ I don't see the big win of this. sc1.staff{<\b1 \b2>} sc1.paper=mypaperdef; + We're not doing a programming language. In this syntax the parser has to lookup what sc1 means, decide if it should copied shallow/deep, decide if has a staff block, switch the mode after it finds that staff @@ -414,9 +396,6 @@ listening, Philip Glass?), but I think that would be something for Mudela version 3. And I think using m4 (or something alike) would be just as convenient. -It might clear things up, if JCN told us what is so special about this -syntax (without the C++ looks). - =head2 Transposition Has to be done. How about: diff --git a/Documentation/make_website b/Documentation/make_website deleted file mode 100755 index d1ec8d4a26..0000000000 --- a/Documentation/make_website +++ /dev/null @@ -1,41 +0,0 @@ -#!/usr/bin/perl -w -sub - set_hrefs -{ - while () { - s#href=([A-Za-z.]+)#href=$base/$1#g; - print HTMLOUT $_; - } -} - -local $base="lilypond/"; -local @examples=("wohltemperirt"); - -system 'pod2html'; - -print "resetting refs.\n"; - -foreach $a (<*.html>) -{ - rename $a, "$a~"; - open HTMLIN, "$a~"; - open HTMLOUT, ">$a"; - set_hrefs; -} - -foreach $a (@examples) { - $texfile="test"; - system "ln ../input/$a.ly ./$a.ly.txt"; - system "cd ..; lilypond input/$a; tex $texfile;". - "dvips -o $texfile.ps $texfile;"; - - # generate the pixmap at twice the size, then rescale (for antialiasing) - if ( ! -f "$a.gif" ) { - system "mv ../$texfile.ps $a.ps; ". - "mv ../lelie.midi $a.midi; ". - "gs -q -sDEVICE=ppmraw -sOutputFile=- -r200 -dNOPAUSE $a.ps -c quit |pnmscale 0.5| ppmtogif > $a.gif"; - } -} - -system "tar hcf website.tar *.html *.gif lelie_logo.png *.ps *.ly.txt *.midi docxx/;" . - "gzip -f9 website.tar;" diff --git a/Generate.make b/Generate.make deleted file mode 100644 index 5be1641e1e..0000000000 --- a/Generate.make +++ /dev/null @@ -1,30 +0,0 @@ -# Generate.make ? - -parsheadorig=$(CCDIR)/parser.tab.h -parsheadnew=$(HEADERDIR)/parser.hh - -# -# take some trouble to avoid overwriting the old y.tab.h, -# because otherwise all dependants would be remade. -$(CCDIR)/parser.cc: $(CCDIR)/parser.y - $(BISON) -d $< - mv $(CCDIR)/parser.tab.c $@ - (if diff $(parsheadorig) $(parsheadnew)>/dev/null; then \ - echo Ignoring $(parsheadorig); \ - else \ - mv $(parsheadorig) $(parsheadnew); \ - fi ) - -$(parsheadnew): $(CCDIR)/parser.cc - -$(HEADERDIR)/version.hh: Variables.make make_version - make_version $(MAJVER) $(MINVER) $(PATCHLEVEL) "$(CXX) $(CXXVER)" > $@ - -$(CCDIR)/%.cc: $(CCDIR)/%.y - $(BISON) -d $< - mv $(CCDIR)/$(shell basename $@ .cc ).tab.h $(HEADERDIR)/$(shell basename $@ .cc).hh - mv $(CCDIR)/$(shell basename $@ .cc ).tab.c $@ - -$(CCDIR)/%.cc: $(CCDIR)/%.l - $(FLEX) -t $< > $@ - diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000000..29161e6fc4 --- /dev/null +++ b/INSTALL @@ -0,0 +1,50 @@ +IMPORTANT: + + if you have downloaded a + + *.pre* + + version, then this is version is *not* meant for producing nice output + (but to keep your patchsets up to date). It might not even compile. + + +INSTALL: + + to make LilyPond, simply type: + + sh configure + make + + assuming you have the gnu development tools, and your make is gnu make, + else try something like: + + MAKE=gmake configure + MAKE=gmake gmake + + \begin{masochist} + Windows NT: + + you need the cygnus win32 gnu port development stuff; have a look + at http://www.cygnus.com/gnu-win32. + + to make LilyPond under, brr, aargh, well, simply type: + + bash bin/configure + make win32 + \end{masochist} + + +SUPPORT + + LilyPond (pl 0.0.39) is known to compile on the following platforms: + + * linux 2.0.28, g++ 2.7.2[.1] + * aix 4.1, g++ 2.7.2 + * windows-nt 4.0, cygnus gnu-win32 beta17.1 (~=g++ 2.7.2) + * linux 2.0.28 X to doze, gcc-go32 (~=g++ 2.7.2) + +Have fun! + + hanwen@stack.nl + jan@digicash.com + diff --git a/Initial.make b/Initial.make deleted file mode 100644 index 416a7fcb6e..0000000000 --- a/Initial.make +++ /dev/null @@ -1,12 +0,0 @@ -include Variables.make - -initdefault: $(CCDIR)/parser.cc $(CCDIR)/lexer.cc hdr/version.hh alldeps - -include Generate.make - -alldeps: #$(ALLDEPS) - touch $(DEPDIR)/dummy.dep - -#$(DEPDIR)/%.dep: $(CCDIR)/%.cc -# $(DODEP) $(CXX) -E $(CXXFLAGS) $^ > /dev/null - diff --git a/Makefile b/Makefile index c990a7246c..b8abfd8b66 100644 --- a/Makefile +++ b/Makefile @@ -1,65 +1,52 @@ -# Makefile -# top level makefile of LilyPond +# +# project LilyPond -- the musical typesetter +# title top level makefile for LilyPond +# file Makefile +# +# Copyright (c) 1997 by +# Jan Nieuwenhuizen +# Han-Wen Nienhuys +# ...your sort order here, or how to comment-out a comment + +# subdir level: +# +depth = . +# + +# identify module: +# +NAME = lilypond + +# edit in .version only! +MAJOR_VERSION = $(TOPLEVEL_MAJOR_VERSION) +MINOR_VERSION = $(TOPLEVEL_MINOR_VERSION) +PATCH_LEVEL = $(TOPLEVEL_PATCH_LEVEL) +# use to send patches, always empty for released version: +MY_PATCH_LEVEL = $(TOPLEVEL_MY_PATCH_LEVEL) +build = ./$(depth)/lily/.build +# + +# generic variables: +# +include ./$(depth)/make/Variables.make +# + +# descent order into subdirectories: +# +SUBDIRS = flower lib lily m2m \ + Documentation bin init input make tex +# + +# list of distribution files: +# +SYMLINKS = configure +README_FILES = ANNOUNCE COPYING INSTALL NEWS README TODO +DISTFILES= Makefile .version $(README_FILES) $(SYMLINKS) +# + +# generic targets and rules: +# +include ./$(depth)/make/Targets.make +include ./$(depth)/make/Rules.make +# -include Variables.make - -.SUFFIXES: -.SUFFIXES: .cc .o .hh .y .l .pod .txt .1 .dep - - -$(exe): $(obs) - $(STRIPDEBUG) $(STABLEOBS) - $(LINKER) -o $@ $^ $(LOADLIBES) - -$(m2m): $(m2mobs) - $(LINKER) -o $@ $^ $(LOADLIBES) - -.PHONY: clean docxx - -clean: - rm -f $(allexe) $(DOCDIR)/* core $(allobs) - for SUBDIR in $(SUBDIRS); \ - do \ - $(MAKE) SUBDIR=$$SUBDIR -C $$SUBDIR clean;\ - done - -distclean: clean - rm -f version.hh $(gencc) .GENERATE *~ $(ALLDEPS) - -all: $(exe) $(m2m) doc - -# value of $(OSTYPE) on windhoos; "make $OSTYPE" if you use bash :-) -win32: - $(MAKE) -C . CXX=g++ - -doc: - $(MAKE) -C Documentation doc - -# doc++ documentation of classes -docxx: $(progdocs) - doc++ -kp -d $(DOCDIR) $^ - - -include $(DEPDIR)/*.dep - -$(OBJECTDIR)/%.o: $(CCDIR)/%.cc - $(DODEP)\ - $(CXX) -c $(CXXFLAGS) $(OUTPUT_OPTION) - -$(OBJECTDIR)/version.o: $(obs) $(HEADERDIR)/version.hh - -include Generate.make - -dist: - -mkdir $(DDIR) - ln $(DFILES) $(DDIR)/ - for SUBDIR in $(SUBDIRS); \ - do mkdir $(DDIR)/$$SUBDIR; \ - $(MAKE) SUBDIR=$$SUBDIR -C $$SUBDIR dist;\ - done - tar cfz $(DNAME).tar.gz $(DNAME)/ - rm -rf $(DDIR)/ - -TAGS: - $(MAKE) -C $(HEADERDIR) TAGS - $(MAKE) -C $(CCDIR) TAGS diff --git a/NEWS b/NEWS index 130c3b9656..4441132305 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,40 @@ +pl 39-1 + - doze target (for 16 bit dos xcompiler: gcc-go32) +Internal + - make/User.make; C..FLAGS sorted out +Bugfix + - make clean... + +pl 39 + - new make structure, featuring: + * top-level/sub-level build + * auto custom-library dependencies/build + * top-level/sub-level dist + * minimal(? can even smaller) specific Makefiles + * which makes for simple lib/exe module split (make/Template.make) + * integrated flowerlib + * all stuff into subbirs (make/Stuff.make) + * all headers into /include dirs (make/Include.make) + * all output into /out (executables into bin/) + * more make features, like make config, make help + * small lily lib + * lilypond-x.x.x/.version for toplevel lily version + * lilypond-x.x.x//.version for version (eg: flower) + * versioning using additional optional MY_PATCH_LEVEL + for easy make_patch + + - bin/cptogen + +Internal + - generic m2m header: m2m.hh + +Bugfix + - small fixes, make, dist, configure + +pl 38-5 + - all of the below, e.g. new filenames and new makefile + structure patches merged + pl 38 Internal @@ -7,6 +44,19 @@ Internal intrinsically hierarchical. All walker communication is done via a "top level" register. +pl 37-3 + - m2m handles voices + - instrument, track_name, copyright/left stuff for m2m/ly + +Internal + - Midi_voice + +pl 37-1 + - text, key, tempo event in midi output/ly input + +Internal + - simple makefile structure, allows for multiple projects + ****** pl 37 diff --git a/README b/README index 83f807a7a0..5bfa9c21c5 100644 --- a/README +++ b/README @@ -15,9 +15,6 @@ To generate the pretty-printed docs, do this: make doc -in the top-level dir - - ====================== NOTE: diff --git a/Sources.make b/Sources.make deleted file mode 100644 index df8d33f407..0000000000 --- a/Sources.make +++ /dev/null @@ -1,135 +0,0 @@ -# Sources.make -# sourcefiles to be shipped. Also used for dependencies - -hdr=bar.hh bar-reg.hh beam.hh\ - binary-source-file.hh\ - boxes.hh break.hh class-name.hh clef-reg.hh clef-item.hh\ - colhpos.hh commandrequest.hh \ - complex-walker.hh complex-staff.hh\ - const.hh debug.hh dimen.hh directional-spanner.hh\ - glob.hh grouping.hh headreg.hh idealspacing.hh\ - identifier.hh identparent.hh \ - input-music.hh input-score.hh input-staff.hh\ - input-file.hh\ - item.hh key.hh key-item.hh\ - key-reg.hh\ - keyword.hh leastsquares.hh lexer.hh linespace.hh \ - local-key-item.hh local-key-reg.hh lookup.hh \ - lyric-item.hh lyricstaff.hh lyricwalker.hh\ - main.hh meter.hh meter-reg.hh\ - midi-def.hh midi-item.hh midi-output.hh midi-stream.hh\ - midi-walker.hh\ - misc.hh\ - molecule.hh moment.hh musicalrequest.hh\ - notehead.hh notename.hh offset.hh paper-def.hh\ - parseconstruct.hh pcol.hh proto.hh\ - pscore.hh pstaff.hh qlp.hh\ - qlpsolve.hh register.hh registergroup.hh reqtodo.hh \ - request.hh rest.hh score-column.hh score.hh\ - scoreline.hh score-walker.hh script.hh script-def.hh script-reg.hh \ - slur.hh slur-reg.hh source.hh source-file.hh\ - spanner.hh staff.hh\ - staff-elem.hh staff-elem-info.hh staffline.hh staffsym.hh stem-beam-reg.hh\ - staff-column.hh stem.hh staff-walker.hh symbol.hh symtable.hh\ - tex.hh text-def.hh \ - textitem.hh text-reg.hh textspanner.hh time-description.hh \ - tex-stream.hh voice.hh\ - voice-element.hh voice-regs.hh voice-group-regs.hh walkregs.hh - -mycc=bar.cc bar-reg.cc beam.cc \ - binary-source-file.cc\ - boxes.cc break.cc calcideal.cc clef-reg.cc\ - clef-item.cc colhpos.cc commandrequest.cc\ - complex-staff.cc complex-walker.cc \ - debug.cc dimen.cc\ - directional-spanner.cc\ - grouping.cc groupregs.cc headreg.cc\ - idealspacing.cc identifier.cc\ - input-music.cc input-score.cc\ - input-staff.cc\ - input-file.cc\ - item.cc key.cc key-item.cc \ - key-reg.cc keyword.cc\ - leastsquares.cc lexerinit.cc linespace.cc \ - local-key-item.cc local-key-reg.cc lookup.cc\ - lyric-item.cc lyricstaff.cc lyricwalker.cc\ - main.cc meter.cc meter-reg.cc\ - midi-def.cc midi-item.cc midi-output.cc midi-stream.cc\ - midi-walker.cc misc.cc molecule.cc mylexer.cc note.cc\ - notehead.cc notename.cc\ - paper-def.cc pcol.cc pscore.cc pstaff.cc qlp.cc qlpsolve.cc\ - register.cc registergroup.cc request.cc rest.cc\ - score-column.cc score.cc\ - scoreline.cc scores.cc score-walker.cc script.cc\ - script-def.cc script-reg.cc slur.cc\ - slur-reg.cc source.cc source-file.cc\ - spanner.cc staff.cc\ - staff-elem.cc staffline.cc staffsym.cc\ - stem-beam-reg.cc staff-column.cc stem.cc\ - staff-elem-info.cc staff-walker.cc symbol.cc\ - symtable.cc tex.cc texbeam.cc\ - texslur.cc text-def.cc textitem.cc text-reg.cc textspanner.cc\ - time-description.cc tex-stream.cc voice.cc voiceelt.cc \ - voice-regs.cc voice-group-regs.cc\ - walkregs.cc warn.cc windhoos-suck-suck-suck-thank-you-cygnus.cc wordwrap.cc\ - template1.cc template2.cc template3.cc template4.cc\ - template5.cc template6.cc version.cc - -# a bit of a hack to keep exec size under control. -stablecc=request.cc bar.cc boxes.cc break.cc \ - item.cc keyword.cc leastsquares.cc \ - molecule.cc meter.cc\ - paper-def.cc parser.cc lexer.cc pstaff.cc qlp.cc qlpsolve.cc\ - template1.cc template2.cc template3.cc template4.cc\ - template5.cc template6.cc version.cc tex-stream.cc tex.cc\ - voice.cc wordwrap.cc spanner.cc - - -# m2m headers -# -mym2mhh=\ - duration.hh\ - lily-stream.hh\ - midi-event.hh\ - midi-main.hh\ - midi-score.hh\ - midi-track.hh\ - my-midi-lexer.hh\ - my-midi-parser.hh\ - track-column.hh\ - -# - -# m2m shared headers -# -mym2msharedhh=\ - binary-source-file.hh\ - -# - -# m2m source -# -mym2mcc=\ - duration.cc\ - lily-stream.cc\ - midi-event.cc\ - midi-main.cc\ - midi-score.cc\ - midi-template.cc\ - midi-track.cc\ - my-midi-lexer.cc\ - my-midi-parser.cc\ - track-column.cc\ - -# - -# m2m shared source -# -mym2msharedcc=\ - binary-source-file.cc\ - input-file.cc\ - source-file.cc\ - source.cc\ - -# - diff --git a/TODO b/TODO index e9824ff756..87d3ef806c 100644 --- a/TODO +++ b/TODO @@ -17,6 +17,13 @@ before 0.1 This is an assorted collection of stuff that will be done, might be done, or is an idea that I want to think about +STUFF + * generate all (.hh) files into out dirs + + * sort out headers, see m2m + + * do platform stuff: configure, header(s), targets, build (out?) + BUGS * plet bugs: scales.ly @@ -175,4 +182,4 @@ IDEAS * caching breakpoints - * use exceptions iso assert? \ No newline at end of file + * use exceptions iso assert? diff --git a/Variables.make b/Variables.make deleted file mode 100644 index 1d8348bb86..0000000000 --- a/Variables.make +++ /dev/null @@ -1,130 +0,0 @@ -# -*-Makefile-*- - -# version info -MAJVER=0 -MINVER=0 -PATCHLEVEL=38 - - - -#### -#### USER CONFIGURABLE -#### - -#PROFILEFLAG=-pg -OPTIFLAG=-DNDEBUG -DNPRINT -O2 -DEBUGFLAG=-g - -# uncomment for windhoos -# CXX=g++ - -# turn off -pipe if linker doesn't support it -EXTRACXXFLAGS=-pipe -Wall -W -Wmissing-prototypes -DSTRING_UTILS_INLINED - -# -# -lefence = ElectricFence. -# -# ElectricFence is a memory debugger which uses the -# VM hardware to trap malloc/free errors. -# - -EXTRALIB+= #-lefence - -#### -#### END USER CONFIGURABLE part. -#### - -ifdef PROFILEFLAG - DEFINES+=$(OPTIFLAG) $(PROFILEFLAG) - EXTRALIB+=-pg -endif - -ifndef DEBUGFLAG - DEFINES+=$(OPTIFLAG) -else - DEFINES+=$(DEBUGFLAG) -endif - - - -VERSION=$(MAJVER).$(MINVER).$(PATCHLEVEL) -CXXVER=`$(CXX) --version` - -# directories -TOPDIR := $(shell if [ "$$PWD" != "" ]; then echo $$PWD; else pwd; fi) - -OBJECTDIR=objects -HEADERDIR=hdr -CCDIR=src -INITDIR=init -DEPDIR=deps -INPUTDIR=input - -# -# -include Sources.make - -# UGH, this sux! -gencc=parser.cc lexer.cc -cc=$(mycc) $(gencc) -mym2mgencc=midi-parser.cc midi-lexer.cc -m2mcc=$(mym2mcc) $(mym2mgencc) $(mym2msharedcc) - -MY_CCSOURCE=$(addprefix $(CCDIR)/, $(mycc)) -CCSOURCE=$(addprefix $(CCDIR)/, $(cc)) - -obs=$(addprefix $(OBJECTDIR)/,$(cc:.cc=.o)) -m2mobs=$(addprefix $(OBJECTDIR)/,$(m2mcc:.cc=.o)) - -allcc=$(mycc) $(mym2mcc) -allobs=$(obs) $(m2mobs) -allexe=$(exe) $(m2m) -M2MCCSOURCE=$(addprefix $(CCDIR)/, $(m2mcc)) -ALLDEPS=$(addprefix $(DEPDIR)/,$(cc:.cc=.dep)) -STABLEOBS=$(addprefix $(OBJECTDIR)/,$(stablecc:.cc=.o)) -allhdr=$(hdr) $(mym2mhh) -HEADERS=$(addprefix $(HEADERDIR)/,$(allhdr)) -progdocs=$(HEADERS) $(MY_CCSOURCE) - -#dist -.EXPORT_ALL_VARIABLES: - -DOCDIR=docxx - -PACKAGENAME=lilypond -DNAME=$(PACKAGENAME)-$(VERSION) -M2MNAME=m2m - -# distribution files. -othersrc=lexer.l parser.y midi-lexer.l midi-parser.y -SCRIPTS=make_version make_patch genheader clearlily -MAKFILES=Makefile Variables.make Sources.make Initial.make Generate.make \ - configure -OFILES=COPYING README NEWS TODO ANNOUNCE -IFILES= titledefs.tex lilyponddefs.tex \ - ltest.tex test.tex .dstreamrc dimen.tex -DFILES=$(MAKFILES) $(OFILES) $(IFILES) $(SCRIPTS) - -#compiling -LOADLIBES=-L$(FLOWERDIR) -lflower $(EXTRALIB) -lg++ -FLOWERDIR=../flower - -CXXFLAGS=$(DEFINES) -I$(HEADERDIR) -I$(FLOWERDIR) $(EXTRACXXFLAGS) -FLEX=flex -BISON=bison -exe=$(PACKAGENAME) -m2m=$(M2MNAME) -OUTPUT_OPTION=$< -o $@ -DDIR=$(TOPDIR)/$(DNAME) -SUBDIRS=Documentation $(OBJECTDIR) $(CCDIR) $(HEADERDIR) $(INITDIR) $(DEPDIR) \ - $(INPUTDIR) - -depfile=deps/$(subst .o,.dep,$(notdir $@)) -DODEP=rm -f $(depfile); DEPENDENCIES_OUTPUT="$(depfile) $(OBJECTDIR)/$(notdir $@)" - -STRIPDEBUG=true #replace to do stripping of certain objects -LINKER=$(CXX) -include Site.make - -TAGSACTION=etags -l c++ --no-defines - diff --git a/bin/Makefile b/bin/Makefile new file mode 100644 index 0000000000..2549e4255f --- /dev/null +++ b/bin/Makefile @@ -0,0 +1,20 @@ +# bin/Makefile + +# subdir level: +# +depth = .. +# + +build = ./$(depth)/lily/.build + +# generic stuff/Makefile +# +include ./$(depth)/make/Stuff.make +# + +# list of distribution files: +# +SCRIPTS = clearlily configure cpgento genheader make_patch make_fversion make_version make_website +DISTFILES = Makefile $(SCRIPTS) +# + diff --git a/bin/clearlily b/bin/clearlily new file mode 100755 index 0000000000..983454dad3 --- /dev/null +++ b/bin/clearlily @@ -0,0 +1,8 @@ +#!/bin/sh + +# unclobber current dir. +rm -vf *.aux *.log `grep -li "^% Creator: LilyPond" *.out` *.orig *~ + +# docxx mess +rm -vf *.class HIER*.html dxxgifs.tex gifs.db icon?.gif logo.gif down.gif \ + aindex.html index.html diff --git a/bin/configure b/bin/configure new file mode 100755 index 0000000000..0c647c284d --- /dev/null +++ b/bin/configure @@ -0,0 +1,85 @@ +#!/bin/sh +# +# project LilyPond -- the musical typesetter +# title (bash/sh/ksh) script to setup library and auto generated files +# file bin/configure +# +# Copyright (c) 1997 by +# Han-Wen Nienhuys +# Jan Nieuwenhuizen +# + +MAKE=${MAKE:-make} +NEEDFLOWERVER=1.1.6 +PREFIX=${PREFIX:-.} + + +############# +############# + +# without "function" ok for ksh, bash +setversion() { + eval `sed -n 's/^\([A-Z_]*\)[ ]*=[ ]*\([^ \#]*\).*$/\1=\2/p' $1` +# NEWVER=$TOPLEVEL_MAJOR_VERSION.$TOPLEVEL_MINOR_VERSION.$TOPLEVEL_PATCH_LEVEL$TOPLEVEL_MY_PATCH_LEVEL + NEWVER=$MAJOR_VERSION.$MINOR_VERSION.$PATCH_LEVEL$MY_PATCH_LEVEL + echo + echo "Current version ("`pwd`") is:" + echo " $NEWVER" + echo +} + +do_outdir() { + if [ \! -d $1/out ] + then + mkdir $1/out + echo 0 > $1/.build + fi +} + +echo using PREFIX=$PREFIX +echo I need Flower version $NEEDFLOWERVER + +flowertar=flower-$NEEDFLOWERVER + +#ugh +do_outdir flower/lib +do_outdir Documentation +do_outdir lib +do_outdir lily +do_outdir m2m + +# mmm +if [ -x flower ] +then + echo Found flowerdir +else + if [ -d $flowertar ] + then + ln -fs $flowertar flower + elif [ -d ../$flowertar ] + then + ln -fs ../$flowertar flower + else + echo "can't find $flowertar" + exit 1; + fi +fi + +echo Configuring Flower Library +setversion ./flower/.version +if [ $NEWVER != $NEEDFLOWERVER ]; then + echo "You seem to be having an incorrect version of the Flower library" +else + echo "You got the correct Flower version." +fi + +#ugh +echo '#define LIBDIR "'$PREFIX'/"'> lib/out/config.hh +touch flower/lib/out/flower-config.hh +touch make/Site.make +$MAKE -C make -f Initial.make + +echo "The sources are ready for compiling. " +echo "To make sure that you don't have any stale dependencies: do" +echo " make clean" + diff --git a/bin/cpgento b/bin/cpgento new file mode 100755 index 0000000000..2bb4da29af --- /dev/null +++ b/bin/cpgento @@ -0,0 +1,49 @@ +#!/bin/sh +# cpgento +# + +if test $# -ne 1 +then + echo "Usage: " + echo " cpgento LOCATION, e.g.:"; + echo + echo " cpgento /mnt/aix/usr/src/lily" + echo " CP=rcp cpgento fred@pcnov095.win.tue.nl:music/lily" + exit 1 +fi + +MAKE=${MAKE:-make} +CP=${CP:-cp} + +genlily="out/parser.hh out/parser.cc out/lexer.cc" +echo generating $genlily ... +$MAKE -C lily $genlily + +genm2m="out/midi-parser.hh out/midi-parser.cc out/midi-lexer.cc" +echo generating $genm2m ... +$MAKE -C m2m $genm2m + +lilydir=`pwd | sed "s/.*\///"` +todir=$1/$lilydir +echo "copying $lilydir -> $todir" + +cpto() { + name=$1 + tostuff=$todir/$name/out + genstuff="$2" + if [ "$CP" = "cp" -a \! -d $tostuff ] + then + echo mkdir -p $tostuff + mkdir -p $tostuff + fi + echo $CP $genstuff $tostuff + (cd $name; $CP $genstuff $tostuff) +} + +cpto lily "$genlily" +cpto m2m "$genm2m" + +# if you cannot gen the above, you-ll probably want: +flexlexerh=/usr/include/FlexLexer.h +cpto lib $flexlexerh + diff --git a/bin/genheader b/bin/genheader new file mode 100755 index 0000000000..7c36afe0ae --- /dev/null +++ b/bin/genheader @@ -0,0 +1,31 @@ +#!/usr/bin/perl -w + +die "arg needed\n" if (!($#ARGV+1)); +my $fn = $ARGV[0]; +my $hh_q = ($fn =~ /hh$/ ); +my $MAILADRESS=$ENV{MAILADRESS}; +my @pw=(getpwuid($<)); +my $username=$pw[6]; +my $what="implement "; +$what = "declare " if ($hh_q); +my $headstr ="/* + $fn -- $what + + source file of the LilyPond music typesetter + + (c) 1997 $username <$MAILADRESS> +*/\n"; + +my $startdef= $fn; +$startdef =~ s/[\.-]/_/g; +$startdef =~ tr/a-z/A-Z/; +my $terminatestr="\n"; +if ($hh_q) { + $headstr .= "\n\n#ifndef $startdef\n#define $startdef\n"; + $terminatestr .= "#endif // $startdef\n" +} + +print $headstr, $terminatestr; + + + diff --git a/bin/make_fversion b/bin/make_fversion new file mode 100755 index 0000000000..185eaae445 --- /dev/null +++ b/bin/make_fversion @@ -0,0 +1,11 @@ +#!/bin/sh +echo '#ifndef FVERSION_HH' +echo '#define FVERSION_HH' +echo '#define FMAJOR_VERSION ' "$1" +echo '#define FMINOR_VERSION ' "$2" +echo '#define FPATCH_LEVEL ' "$3" +echo '#define FMY_PATCH_LEVEL ' "$4" +echo '#define FBUILD ' "$5" +echo '#define FVERSIONSTR "'$1.$2.$3$4 \#$5'"' +echo '#define FCOMPILER "'$6'"' +echo '#endif' diff --git a/bin/make_patch b/bin/make_patch new file mode 100755 index 0000000000..290e2e33da --- /dev/null +++ b/bin/make_patch @@ -0,0 +1,41 @@ +#!/bin/sh + +case $# in +0) echo make_patch old new name + exit 1;; +esac + +old=$1 +new=$2 +nm=$3- + +newarc=../releases/$nm$new.tar.gz +oldarc=../releases/$nm$old.tar.gz + + +if [ ! -x $nm$new ] +then + echo untarring .. + if [ ! -f $newarc ] + then + echo cant find $newarc + exit + fi + tar zfxv $newarc +fi +if [ ! -x $nm$old ] +then + echo untarring + + if [ ! -f $oldarc ] + then + echo cant find oldarc + exit + fi + tar zfxv $oldarc +fi + +#(cd $nm$old; touch depend; make clean) +#(cd $nm$new; touch depend; make clean) +(cd $nm$new; diff -urP ../$nm$old . > ../patch-$new) +rm -rf $nm$old $nm$new diff --git a/bin/make_version b/bin/make_version new file mode 100755 index 0000000000..fe5cb05c89 --- /dev/null +++ b/bin/make_version @@ -0,0 +1,11 @@ +#!/bin/sh +echo '#ifndef VERSION_HH' +echo '#define VERSION_HH' +echo '#define MAJOR_VERSION ' "$1" +echo '#define MINOR_VERSION ' "$2" +echo '#define PATCH_LEVEL ' "$3" +echo '#define MY_PATCH_LEVEL ' "$4" +echo '#define BUILD ' "$5" +echo '#define VERSIONSTR "'$1.$2.$3$4 \#$5'"' +echo '#define COMPILER "'$6'"' +echo '#endif' diff --git a/bin/make_website b/bin/make_website new file mode 100755 index 0000000000..844e60bbd1 --- /dev/null +++ b/bin/make_website @@ -0,0 +1,41 @@ +#!/usr/bin/perl -w +sub + set_hrefs +{ + while () { + s#href=([A-Za-z.]+)#href=$base/$1#g; + print HTMLOUT $_; + } +} + +local $base="lilypond/"; +local @examples=("wohltemperirt"); + +system 'pod2html'; + +print "resetting refs.\n"; + +foreach $a (<*.html>) +{ + rename $a, "$a~"; + open HTMLIN, "$a~"; + open HTMLOUT, ">$a"; + set_hrefs; +} + +foreach $a (@examples) { + $texfile="test"; + system "ln ../input/$a.ly ./$a.ly.txt"; + system "cd ..; lilypond input/$a; tex $texfile;". + "dvips -o $texfile.ps $texfile;"; + + # generate the pixmap at twice the size, then rescale (for antialiasing) + if ( ! -f "$a.gif" ) { + system "mv ../$texfile.ps $a.ps; ". + "mv ../lelie.midi $a.midi; ". + "gs -q -sDEVICE=ppmraw -sOutputFile=- -r200 -dNOPAUSE $a.ps -c quit |pnmscale 0.5| ppmtogif > $a.gif"; + } +} + +system "cd out; tar hcf ../website.tar *.html *.gif lelie_logo.png *.ps *.ly.txt *.midi docxx/;" . + "gzip -f9 website.tar;" diff --git a/clearlily b/clearlily deleted file mode 100755 index 983454dad3..0000000000 --- a/clearlily +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh - -# unclobber current dir. -rm -vf *.aux *.log `grep -li "^% Creator: LilyPond" *.out` *.orig *~ - -# docxx mess -rm -vf *.class HIER*.html dxxgifs.tex gifs.db icon?.gif logo.gif down.gif \ - aindex.html index.html diff --git a/configure b/configure deleted file mode 100755 index fec8a5617d..0000000000 --- a/configure +++ /dev/null @@ -1,58 +0,0 @@ -#!/bin/sh - -# script to setup library and auto generated files. - -function setversion() { - eval `sed -n 's/^\([A-Z]*\)=\([p0-9].*\)$/\1=\2/p' Variables.make` - NEWVER=$MAJVER.$MINVER.$PATCHLEVEL - echo - echo "Current version ("`pwd`") is $NEWVER" - echo -} - -MAKE=${MAKE:-make} -PREFIX=${PREFIX:-.} -NEEDFLOWERVER=1.1.4 - -echo using PREFIX=$PREFIX -echo I need Flower version $NEEDFLOWERVER - -flowertar=flower-$NEEDFLOWERVER -here=`pwd` -cd .. - -if [ -x flower ] -then - echo Found flowerdir -else - - if [ ! -d $flowertar ] - then - echo "can't find $flowertar" - exit 1; - fi - rm flower - ln -s $flowertar flower -fi - -echo Compiling Library -{ - cd flower; - setversion - if [ $NEWVER != $NEEDFLOWERVER ]; then - echo "You seem to be having an incorrect version of the Flower library" - else - echo "You got the correct Flower version." - fi - $MAKE -} - -cd $here - -echo '#define LIBDIR "'$PREFIX'/"'> hdr/config.hh -touch Site.make -$MAKE -f Initial.make - -echo "The sources are ready for compiling. " -echo "To make sure that you don't have any stale dependencies: do" -echo " make clean" diff --git a/configure b/configure new file mode 120000 index 0000000000..58b4a5f592 --- /dev/null +++ b/configure @@ -0,0 +1 @@ +bin/configure \ No newline at end of file diff --git a/deps/Makefile b/deps/Makefile deleted file mode 100644 index 79265b1c0f..0000000000 --- a/deps/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -DISTFILES=Makefile dummy.dep - - - -dummy.dep: - touch dummy.dep - - -dist: $(DISTFILES) - ln $(DISTFILES) $(DDIR)/$(SUBDIR) - -clean: - true diff --git a/deps/dummy.dep b/deps/dummy.dep deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/dimen.tex b/dimen.tex deleted file mode 100644 index e53263181d..0000000000 --- a/dimen.tex +++ /dev/null @@ -1,49 +0,0 @@ -\font\musicfont=musixsps -\font\slurfont=xslu16 -\def\thefont{\musicfont} - -\def\mb#1{{\thefont\char#1}} - -\newdimen\wid -\newdimen\inc -\newdimen\here -\def\hruler#1{% - \wid=#1pt - \inc=\wid - \divide\inc by #1 - \divide\wid by 2 - \here=-\wid - \loop\ifdim\here<\wid\advance\here by\inc - \hbox to0pt{\kern\here\vrule width0.05pt height 2pt\hss}% - \repeat% -} - -\def\vruler#1{% - \wid=#1pt - \inc=\wid - \divide\inc by #1 - \divide\wid by 2 - \here=-\wid - \loop\ifdim\here<\wid\advance\here by\inc - \vbox to0pt{\vskip\here\vrule width2pt height 0.05pt\vss}% - \repeat% -} -\def\twhrul{\hbox to 0pt{\hbox{\hruler{20}\vrule - width0.1pt height 3ptdepth 1pt}}} -\def\twvrul{\hbox{\vbox to 20pt{\vruler{20}\vrule - width3pt height 0.1pt}}} - -\def\doitem#1{ - #1 % - %\twvrul%doesn't work - \hbox to 50pt{\qquad\twhrul\mb{#1}\hss}\setbox0=\hbox{\mb{#1}} width \the\wd0\ depth \the\dp0 \ height \the\ht0} - -\newcount\n -\def\charn{\n=-1 - \loop\ifnum\n<255\advance\n by1 - \doitem{\number\n}\endgraf\repeat} - - - \charn - -\bye \ No newline at end of file diff --git a/flower/.version b/flower/.version new file mode 100644 index 0000000000..5a44cc8816 --- /dev/null +++ b/flower/.version @@ -0,0 +1,6 @@ +MAJOR_VERSION = 1 +MINOR_VERSION = 1 +PATCH_LEVEL = 6 +# use to send patches, always empty for released version: +MY_PATCH_LEVEL = -1# include separator: "-1" or ".a" +# diff --git a/flower/Makefile b/flower/Makefile index 447072b75a..779f1e5b82 100644 --- a/flower/Makefile +++ b/flower/Makefile @@ -3,11 +3,20 @@ include Variables.make $(staticlib): $(obs) fversion.hh $(AR) cr libflower.a $(obs) -include depend +include deps/*.dep + +deps/*.dep: + touch deps/dummy.dep depend: Sources.make $(CXX) $(CXXFLAGS) -MM $(cc) > depend + +$(OBJECTDIR)/%.o: $(CCDIR)/%.cc + $(DODEP)\ + $(CXX) -c $(CXXFLAGS) $(OUTPUT_OPTION) + + clean: rm -f $(obs) $(staticlib) fversion.hh @@ -24,9 +33,19 @@ docxx: $(hh) $(cc) $(templatecc) $(inl) dist: -mkdir $(DDIR) ln $(DFILES) $(DDIR)/ - tar cfz $(DNAME).tar.gz $(DDIR)/* + -for SUBDIR in $(SUBDIRS); \ + do mkdir $(DDIR)/$$SUBDIR; \ + $(MAKE) SUBDIR=$$SUBDIR -C $$SUBDIR dist;\ + done + tar cfz $(DNAME).tar.gz $(DNAME)/ rm -rf $(DDIR)/ TAGS: $(ALLSOURCES) etags -CT $(inl) $(cc) $(hh) + + +test: stringtest + +stringtest: $(OBJECTDIR)/stringtest.o + g++ -o $@ $< -L. -lflower \ No newline at end of file diff --git a/flower/NEWS b/flower/NEWS index d6d6d86aed..36c03ddcd4 100644 --- a/flower/NEWS +++ b/flower/NEWS @@ -1,4 +1,7 @@ -pl 1.1.3-1 + +pl 1.1.4 + - great file-renaming. + - String cleanup (binary <-> null terminate), several bugfixes - great renaming of String and String_convert interfaces - more conversions moved (copied actually) to String_convert - String indexing now all base = 0, not found = -1 diff --git a/flower/Sources.make b/flower/Sources.make index 82454e3e3c..4e08bec735 100644 --- a/flower/Sources.make +++ b/flower/Sources.make @@ -1,18 +1,21 @@ -cc=choleski.cc datafile.cc dstream.cc lgetopt.cc matdebug.cc matrix.cc\ -path.cc scalar.cc smat.cc string.cc string-convert.cc stringutil.cc\ -textdb.cc textstream.cc unionfind.cc vector.cc +cc=choleski.cc data-file.cc dstream.cc lgetopt.cc libc-extension.cc matdebug.cc\ + matrix.cc\ + path.cc scalar.cc smat.cc string.cc string-convert.cc stringutil.cc\ + text-db.cc text-stream.cc unionfind.cc vector.cc templatecc=cursor.tcc list.tcc plist.tcc interval.tcc\ pcursor.tcc -inl=link.inl list.inl cursor.inl plist.inl stringdata.inl stringhandle.inl +inl=link.inl list.inl cursor.inl plist.inl string-data.inl string-handle.inl -hh=assoc.hh associter.hh choleski.hh compare.hh cursor.hh dstream.hh\ -fproto.hh handle.hh interval.hh iterate.hh lgetopt.hh link.hh list.hh\ -matrix.hh path.hh pcursor.hh plist.hh rational.hh real.hh scalar.hh\ -smat.hh string.hh string-convert.hh stringhandle.hh stringdata.hh\ -textdb.hh textstream.hh unionfind.hh pqueue.hh\ -varray.hh vector.hh vsmat.hh datafile.hh +hh=assoc.hh assoc-iter.hh choleski.hh compare.hh cursor.hh data-file.hh \ + dstream.hh\ + fproto.hh handle.hh interval.hh iterate.hh lgetopt.hh \ + libc-extension.hh link.hh list.hh\ + matrix.hh path.hh pcursor.hh plist.hh rational.hh real.hh scalar.hh\ + smat.hh string.hh string-convert.hh string-handle.hh string-data.hh\ + text-db.hh text-stream.hh unionfind.hh pqueue.hh\ + varray.hh vector.hh vsmat.hh extra=stringtest.cc diff --git a/flower/TODO b/flower/TODO index d67ab72e9f..2026c95134 100644 --- a/flower/TODO +++ b/flower/TODO @@ -1,4 +1,8 @@ - * disable: const pointer->bool->string + * shared lib. + + * integrate Make mechanisms of flower & lily + + * disable this auto conv: const pointer -> bool -> string * PointerVec ? @@ -8,12 +12,6 @@ * extend Interval - * change String::pos - - s[s.pos('%')] == '%' - - would be nice - * use template handle in handle.hh for strings. * move towards gnu or STL? diff --git a/flower/Variables.make b/flower/Variables.make index d8cca75c97..564acd8c63 100644 --- a/flower/Variables.make +++ b/flower/Variables.make @@ -1,12 +1,12 @@ MAJVER=1 MINVER=1 -PATCHLEVEL=3 +PATCHLEVEL=4 PACKAGENAME=flower #PROFILEFLAG=-pg #DEBUGFLAG= -g -OPTIFLAG= -DNPRINT -O2 -DSTRING_UTILS_INLINED -DNDEBUG +OPTIFLAG= -DNPRINT -O2 -DSTRING_UTILS_INLINED # -DNDEBUG ######################################### @@ -29,11 +29,17 @@ VERSION=$(MAJVER).$(MINVER).$(PATCHLEVEL) DNAME=$(PACKAGENAME)-$(VERSION) include Sources.make +OBJECTDIR=objects +CCDIR=. +obs=$(addprefix $(OBJECTDIR)/,$(cc:.cc=.o)) -obs=$(cc:.cc=.o) staticlib=libflower.a ALLSOURCES=$(hh) $(cc) $(inl) $(templatecc) $(extra) DFILES=$(ALLSOURCES) Makefile Variables.make make_version\ Sources.make TODO README NEWS DDIR=$(DNAME) +depfile=deps/$(subst .o,.dep,$(notdir $@)) +DODEP=rm -f $(depfile); DEPENDENCIES_OUTPUT="$(depfile) $(OBJECTDIR)/$(notdir $@)" +OUTPUT_OPTION=$< -o $@ +SUBDIRS=deps objects diff --git a/flower/assoc.hh b/flower/assoc.hh index 07afb8a27c..99e20914b7 100644 --- a/flower/assoc.hh +++ b/flower/assoc.hh @@ -4,6 +4,9 @@ #include "varray.hh" #include +/** + A helper for Assoc + */ template struct Assoc_ent_ { bool free; @@ -12,7 +15,8 @@ struct Assoc_ent_ { }; -/** mindblowingly stupid Associative array implementation.Hungarian: map +/** mindblowingly stupid Associative array implementation. + Hungarian: map */ template struct Assoc { @@ -62,9 +66,6 @@ public: int i = find_creat(key); arr[i].val = val; } - /* - should create "set" template - */ V& operator[](K key) { return arr[find_creat(key)].val; } diff --git a/flower/associter.hh b/flower/associter.hh deleted file mode 100644 index 34b88df22d..0000000000 --- a/flower/associter.hh +++ /dev/null @@ -1,39 +0,0 @@ -/* - associter.hh -- part of flowerlib - - (c) 1996 Han-Wen Nienhuys -*/ - -#ifndef ASSOCITER_HH -#define ASSOCITER_HH - -#include "assoc.hh" - -/// an iterator for the #Assoc# class -template -struct Assoc_iter { - int i; - Assoc &assoc_; - /// we don't want to be bothered by const correctness - Assoc_iter(const Assoc &a) : - assoc_((Assoc &)a) - { - i= next(0); - } - int next(int j) { - while (j < assoc_.arr.size() && assoc_.arr[j].free) - j++; - return j; - } - bool ok() const { - return i < assoc_.arr.size(); - } - void OK()const { - assert(!ok() || !assoc_.arr[i].free); - } - void operator++(int) { i++; i = next(i); } - K key() { return assoc_.arr[i].key; } - V &val() { return assoc_.arr[i].val; } -}; - -#endif diff --git a/flower/choleski.cc b/flower/choleski.cc index 4202a9b1e5..1d64f949ac 100644 --- a/flower/choleski.cc +++ b/flower/choleski.cc @@ -59,7 +59,7 @@ Choleski_decomposition::Choleski_decomposition(Matrix P) assert((original()-P).norm() / P.norm() < EPS); #endif } - + Matrix Choleski_decomposition::original() const { diff --git a/flower/datafile.cc b/flower/datafile.cc deleted file mode 100644 index e5940b4c40..0000000000 --- a/flower/datafile.cc +++ /dev/null @@ -1,95 +0,0 @@ -#include -#include - -#include "datafile.hh" - -void -Data_file::gobble_white() -{ - char c; - - while ((c=data_get()) == ' ' ||c == '\t') - if (eof()) - break; - - data_unget(c); -} - -String -Data_file::get_word() -{// should handle escape seq's - String s; - - while (1) - { - char c = data_get(); - - if (isspace(c) || eof()) - { - data_unget(c); - break; - } - - - if (c == '\"') - { - rawmode= true; - - while ((c = data_get()) != '\"') - if (eof()) - error("EOF in a string"); - else - s += c; - - - rawmode= false; - } - else - s += c; - } - - return s; -} - -/** get a char - Only class member who uses text_file::get - */ -char -Data_file::data_get() { - char c = get(); - if (!rawmode && c == '#') // gobble comment - { - while ((c = get()) != '\n' && !eof()) - ; - return '\n'; - } - - return c; -} - -/// read line, gobble '\n' -String Data_file::get_line() -{ - char c; - String s; - - while ((c = data_get()) != '\n' && !eof()) - s += c; - return s; -} - -/// gobble stuff before first entry on a line. -void -Data_file::gobble_leading_white() -{ - // eat blank lines. - while (!eof()) { - char c = data_get(); - if (!isspace(c)) { - data_unget(c); - break; - } - } -} - - diff --git a/flower/datafile.hh b/flower/datafile.hh deleted file mode 100644 index 14d57369a3..0000000000 --- a/flower/datafile.hh +++ /dev/null @@ -1,59 +0,0 @@ -/* - datafile.hh -- declare Data_file - - source file of the LilyPond music typesetter - - (c) 1997 Han-Wen Nienhuys -*/ - - -#ifndef DATAFILE_HH -#define DATAFILE_HH - -#include "textstream.hh" - -/// read a data file -class Data_file : private Text_stream -{ - - public: - bool rawmode; - - Text_stream::line; - Text_stream::eof; - Text_stream::get_name; - - char data_get(); - void data_unget(char c) { - unget(c); - } - - /// read line, eat #\n# - String get_line(); - - /// read a word till next space, leave space. Also does quotes - String get_word(); - - /// gobble horizontal white stuff. - void gobble_white(); - - /// gobble empty stuff before first field. - void gobble_leading_white(); - Data_file(String s) : Text_stream(s) { - //*mlog << "(" << s << flush; - rawmode= false; - } - - ~Data_file() { - // *mlog << ")"<=0) + pretty_str = pretty_str.left_str(i); + + int l = pretty_str.index_last_i(' '); // strip until last ' ' + if (l>=0) + pretty_str = pretty_str.nomid_str(0,l+1); + return pretty_str; } static String strip_member(String pret) { - String cl(pret.left_str(pret.index_last_i(':')-1)); - return cl; + int l=pret.index_last_i(':')-1; + if (l>=0) + pret = pret.left_str(l ); + return pret; } Dstream& @@ -46,7 +53,7 @@ Dstream::identify_as(String name) local_silence = (*silent)[idx]; if (classname != idx && !local_silence) { classname=idx; - *os << "[" << classname << ":]"; +// *os << "[" << classname << ":]"; // messy. } return *this; } @@ -59,17 +66,37 @@ Dstream::silence(String s) return (*silent)[s]; } -/** only output possibility. Delegates all conversion to String class. - */ +/** Output a string via the Dstream. This is the only output + interface. It delegates all conversion to String class. */ Dstream & Dstream::operator<<(String s) +{ + output(s); + return *this; +} + +Dstream & +Dstream::operator<<(const void *v_l) +{ + output(String_convert::pointer_str(v_l)); + return *this; +} + +Dstream & +Dstream::operator<<(const char *ch_l) +{ + output(ch_l); + return *this; +} + +void +Dstream::output(String s) { if (local_silence|| !os) - return *this; + return ; for (const char *cp = s ; *cp; cp++) - switch(*cp) - { + switch(*cp) { case '{': case '[': case '(': indentlvl += INDTAB; @@ -92,7 +119,7 @@ Dstream::operator<<(String s) *os << *cp; break; } - return *this; + return ; } @@ -125,6 +152,7 @@ Dstream::Dstream(ostream *r, const char * cfg_nm ) Dstream::~Dstream() -{ +{ delete silent; + assert(!indentlvl) ; } diff --git a/flower/dstream.hh b/flower/dstream.hh index 801b166774..5375304d85 100644 --- a/flower/dstream.hh +++ b/flower/dstream.hh @@ -29,7 +29,7 @@ class Dstream int indentlvl; bool local_silence; String classname; - + void output(String s); Assoc *silent; public: @@ -42,8 +42,13 @@ public: Dstream(ostream *r, const char * rcfile); virtual ~Dstream(); Dstream &identify_as(String s); - + Dstream &operator << (String s); + /** + Output memory locations. + */ + Dstream &operator << (void const *); + Dstream &operator << (char const *); }; #endif diff --git a/flower/fproto.hh b/flower/fproto.hh index 509d25d3fa..57469fead5 100644 --- a/flower/fproto.hh +++ b/flower/fproto.hh @@ -16,25 +16,25 @@ template struct IPointerList; template struct Cursor; template struct PCursor; template struct Link; -template struct Handle ; -templatestruct Interval_t ; +template struct Handle; +templatestruct Interval_t; #include "real.hh" typedef Interval_t Interval; -struct Choleski_decomposition ; +struct Choleski_decomposition; -struct long_option_init ; -struct Getopt_long ; -struct Matrix ; -struct String_data ; -struct String_handle ; +struct Long_option_init; +struct Getopt_long; +struct Matrix; +struct String_data; +struct String_handle; struct String_convert; struct String; -struct virtual_smat ; -struct Vector ; -class Text_stream; -class Data_file ; +struct virtual_smat; +struct Vector ; +struct Text_stream; +struct Data_file; struct Text_db; struct Scalar; typedef unsigned char Byte; diff --git a/flower/lgetopt.cc b/flower/lgetopt.cc index 523d54ee5f..a56c64c6db 100644 --- a/flower/lgetopt.cc +++ b/flower/lgetopt.cc @@ -1,7 +1,6 @@ /* process command line, GNU style. - this is (Copyleft) 1996, Han-Wen Nienhuys, */ #include @@ -10,15 +9,18 @@ #include "lgetopt.hh" long -Getopt_long::intarg() { +Getopt_long::intarg() +{ long l; if (sscanf(optarg, "%ld", &l) != 1) report(E_ILLEGALARG); return l; } -long_option_init * -Getopt_long::parselong() { + +Long_option_init * +Getopt_long::parselong() +{ const char *optnm = argv[optind] + 2 ; assert(*optnm); @@ -64,7 +66,7 @@ Getopt_long::parselong() { ostream & -long_option_init::printon(ostream &errorout) +Long_option_init::printon(ostream &errorout) { if (shortname) errorout <<"-" << shortname; @@ -91,7 +93,8 @@ Getopt_long::report(Errorcod c) *errorout << "requires an argument"<longname << "' does not allow an argument"<longname << "' does not allow an argument"< +# Han-Wen Nienhuys +# + +# subdir level: +# +depth = ../.. +# + +# identify module: +# +NAME = flower +MODULE_NAME = flower +include ./$(depth)/flower/.version +build = ./$(depth)/flower/lib/.build +# + +# generic variables: +# +include ./$(depth)/make/Variables.make +# + +# descent order into subdirectories: +# +SUBDIRS = include +# + +# to be remade each build: +# +VERSION_DEPENDENCY =# +# + +# list of c++ header files: +# +HHFILES = # $(shell ls include/*.hh) +# + +# list of c++ source files: +# +CCFILES = $(shell ls *.cc) +# + +# list of other source files: +# +EXTRA_SOURCE_FILES =# $(shell ls *.y *.l) +# + +# list of distribution files: +# +DISTFILES = Makefile $(HHFILES) $(CCFILES) $(EXTRA_SOURCE_FILES) +# + +# list of custom libraries: +# +# yes, i know about the -L and -l options, +# but these libraries get rebuild when needed. +CUSTOMLIBES = \ + +LOADLIBES += +# + +# main target of this module: +# +# MAINTARGET = $(EXECUTABLE) +# MAINTARGET = $(LIBRARY) +# MAINTARGET = $(bindir)/$(EXECUTABLE)# huh? +MAINTARGET = $(libdir)/$(LIBRARY)# huh? + +default: $(MAINTARGET) +# + +# sic. +$(include-flower)/flower-config.hh: + touch $@ + +# generic targets and rules: +# +include ./$(depth)/make/Targets.make +include ./$(depth)/make/Rules.make +# + +# auto dependencies: +# +-include ./$(outdir)/*.dep +# + diff --git a/flower/lib/choleski.cc b/flower/lib/choleski.cc new file mode 100644 index 0000000000..1d64f949ac --- /dev/null +++ b/flower/lib/choleski.cc @@ -0,0 +1,91 @@ +#include "choleski.hh" +const Real EPS = 1e-7; // so sue me. Hard coded + +Vector +Choleski_decomposition::solve(Vector rhs)const +{ + int n= rhs.dim(); + assert(n == L.dim()); + Vector y(n); + + // forward substitution + for (int i=0; i < n; i++) { + Real sum(0.0); + for (int j=0; j < i; j++) + sum += y(j) * L(i,j); + y(i) = (rhs(i) - sum)/L(i,i); + } + for (int i=0; i < n; i++) + y(i) /= D(i); + + // backward subst + Vector &x(rhs); // using input as return val. + for (int i=n-1; i >= 0; i--) { + Real sum(0.0); + for (int j=i+1; j < n; j++) + sum += L(j,i)*x(j); + x(i) = (y(i) - sum)/L(i,i); + } + return x; +} + +/* + Standard matrix algorithm. + */ + +Choleski_decomposition::Choleski_decomposition(Matrix P) + : L(P.dim()), D(P.dim()) +{ + int n = P.dim(); + assert((P-P.transposed()).norm()/P.norm() < EPS); + + L.unit(); + for (int k= 0; k < n; k++) { + for (int j = 0; j < k; j++){ + Real sum(0.0); + for (int l=0; l < j; l++) + sum += L(k,l)*L(j,l)*D(l); + L(k,j) = (P(k,j) - sum)/D(j); + } + Real sum=0.0; + + for (int l=0; l < k; l++) + sum += sqr(L(k,l))*D(l); + Real d = P(k,k) - sum; + D(k) = d; + } + +#ifdef NDEBUG + assert((original()-P).norm() / P.norm() < EPS); +#endif +} + +Matrix +Choleski_decomposition::original() const +{ + Matrix T(L.dim()); + T.set_diag(D); + return L*T*L.transposed(); +} + +Matrix +Choleski_decomposition::inverse() const +{ + int n=L.dim(); + Matrix invm(n); + Vector e_i(n); + for (int i = 0; i < n; i++) { + e_i.set_unit(i); + Vector inv(solve(e_i)); + for (int j = 0 ; j +#include + +#include "data-file.hh" + +void +Data_file::gobble_white() +{ + char c; + + while ((c=data_get()) == ' ' ||c == '\t') + if (eof()) + break; + + data_unget(c); +} + +String +Data_file::get_word() +{// should handle escape seq's + String s; + + while (1) + { + char c = data_get(); + + if (isspace(c) || eof()) + { + data_unget(c); + break; + } + + + if (c == '\"') + { + rawmode= true; + + while ((c = data_get()) != '\"') + if (eof()) + error("EOF in a string"); + else + s += c; + + + rawmode= false; + } + else + s += c; + } + + return s; +} + +/** get a char + Only class member who uses text_file::get + */ +char +Data_file::data_get() { + char c = get(); + if (!rawmode && c == '#') // gobble comment + { + while ((c = get()) != '\n' && !eof()) + ; + return '\n'; + } + + return c; +} + +/// read line, gobble '\n' +String Data_file::get_line() +{ + char c; + String s; + + while ((c = data_get()) != '\n' && !eof()) + s += c; + return s; +} + +/// gobble stuff before first entry on a line. +void +Data_file::gobble_leading_white() +{ + // eat blank lines. + while (!eof()) { + char c = data_get(); + if (!isspace(c)) { + data_unget(c); + break; + } + } +} + + diff --git a/flower/lib/dstream.cc b/flower/lib/dstream.cc new file mode 100644 index 0000000000..e6fdbc0e4d --- /dev/null +++ b/flower/lib/dstream.cc @@ -0,0 +1,158 @@ +#include +#include "assoc.hh" +#include "dstream.hh" +#include "scalar.hh" +#include "text-db.hh" +#include "string-convert.hh" + +/// indent of each level +const INDTAB = 2; + +/* + should use Regexp library. + */ +static String +strip_pretty(String pretty_str) +{ + int i = pretty_str.index_i('('); + if (i>=0) + pretty_str = pretty_str.left_str(i); + + int l = pretty_str.index_last_i(' '); // strip until last ' ' + if (l>=0) + pretty_str = pretty_str.nomid_str(0,l+1); + return pretty_str; +} + +static String +strip_member(String pret) +{ + int l=pret.index_last_i(':')-1; + if (l>=0) + pret = pret.left_str(l ); + return pret; +} + +Dstream& +Dstream::identify_as(String name) +{ + if (!os) + return *this; + + String mem(strip_pretty(name)); + String cl(strip_member(mem)); + String idx = cl; + + if (silent->elt_query(mem)) + idx = mem; + else if (silent->elt_query(cl)) + idx = cl; + else { + (*silent)[idx] = false; + } + local_silence = (*silent)[idx]; + if (classname != idx && !local_silence) { + classname=idx; +// *os << "[" << classname << ":]"; // messy. + } + return *this; +} + +bool +Dstream::silence(String s) +{ + if (!silent->elt_query(s)) + return false; + return (*silent)[s]; +} + +/** Output a string via the Dstream. This is the only output + interface. It delegates all conversion to String class. */ +Dstream & +Dstream::operator<<(String s) +{ + output(s); + return *this; +} + +Dstream & +Dstream::operator<<(const void *v_l) +{ + output(String_convert::pointer_str(v_l)); + return *this; +} + +Dstream & +Dstream::operator<<(const char *ch_l) +{ + output(ch_l); + return *this; +} + +void +Dstream::output(String s) +{ + if (local_silence|| !os) + return ; + + for (const char *cp = s ; *cp; cp++) + switch(*cp) { + case '{': + case '[': + case '(': indentlvl += INDTAB; + *os << *cp; + break; + + case ')': + case ']': + case '}': + indentlvl -= INDTAB; + *os << *cp ; + + assert (indentlvl>=0) ; + break; + + case '\n': + *os << '\n' << String (' ', indentlvl) << flush; + break; + default: + *os << *cp; + break; + } + return ; +} + + +Dstream::Dstream(ostream *r, const char * cfg_nm ) +{ + os = r; + silent = new Assoc; + indentlvl = 0; + if (!os) + return; + + const char * fn =cfg_nm ? cfg_nm : ".dstreamrc"; + { + ifstream ifs(fn); // can't open + if (!ifs) + return; + } + + Text_db cfg(fn); + while (! cfg.eof()){ + Text_record r( cfg++); + if (r.size() != 2) { + r.message("not enough fields in Dstream init."); + continue; + } + (*silent)[r[0]] = (bool)(int)(Scalar(r[1])); + } + +} + + +Dstream::~Dstream() +{ + delete silent; + assert(!indentlvl) ; +} diff --git a/flower/lib/include/Makefile b/flower/lib/include/Makefile new file mode 100644 index 0000000000..36059a888f --- /dev/null +++ b/flower/lib/include/Makefile @@ -0,0 +1,19 @@ +# flower/lib/include/Makefile + +# subdir level: +# +depth = ../../.. +# + +# generic stuff/Makefile +# +include ./$(depth)/make/Include.make +# + +# identify module: +# +MODULE_NAME = flower +include ./$(depth)/flower/.version +build = ./$(depth)/flower/lib/.build +# + diff --git a/flower/lib/include/assoc-iter.hh b/flower/lib/include/assoc-iter.hh new file mode 100644 index 0000000000..34b88df22d --- /dev/null +++ b/flower/lib/include/assoc-iter.hh @@ -0,0 +1,39 @@ +/* + associter.hh -- part of flowerlib + + (c) 1996 Han-Wen Nienhuys +*/ + +#ifndef ASSOCITER_HH +#define ASSOCITER_HH + +#include "assoc.hh" + +/// an iterator for the #Assoc# class +template +struct Assoc_iter { + int i; + Assoc &assoc_; + /// we don't want to be bothered by const correctness + Assoc_iter(const Assoc &a) : + assoc_((Assoc &)a) + { + i= next(0); + } + int next(int j) { + while (j < assoc_.arr.size() && assoc_.arr[j].free) + j++; + return j; + } + bool ok() const { + return i < assoc_.arr.size(); + } + void OK()const { + assert(!ok() || !assoc_.arr[i].free); + } + void operator++(int) { i++; i = next(i); } + K key() { return assoc_.arr[i].key; } + V &val() { return assoc_.arr[i].val; } +}; + +#endif diff --git a/flower/lib/include/assoc.hh b/flower/lib/include/assoc.hh new file mode 100644 index 0000000000..99e20914b7 --- /dev/null +++ b/flower/lib/include/assoc.hh @@ -0,0 +1,78 @@ +#ifndef ASSOC_HH +#define ASSOC_HH + +#include "varray.hh" +#include + +/** + A helper for Assoc + */ +template +struct Assoc_ent_ { + bool free; + K key; + V val; +}; + + +/** mindblowingly stupid Associative array implementation. + Hungarian: map + */ +template +struct Assoc { + Array< Assoc_ent_ > arr; + + /* ************** */ + + int find(K key) const { + for (int i = 0; i < arr.size(); i++) { + if (!arr[i].free && key == arr[i].key) + return i; + } + return -1; + } + int find_creat(K key) { + int free = -1; + for (int i = 0; i < arr.size(); i++) { + if (key == arr[i].key) { + return i; + } else if (arr[i].free ) { + free = i; + } + } + if (free >= 0){ + arr[free].free = false; + arr[free].key = key; + return free; + } + + Assoc_ent_ ae; + ae.free = false; + ae.key = key; + arr.push(ae); + return arr.size() -1; + } +public: + bool elt_query(K key) const { + return find(key) >= 0; + } + void del(K key) { + assert(elt_query(key)); + int i= find(key); + arr[i].free = true; + } + void + add(K key, V val) { + int i = find_creat(key); + arr[i].val = val; + } + V& operator[](K key) { + return arr[find_creat(key)].val; + } + const V& operator[](K key) const { + assert(elt_query(key)); + return arr[find(key)].val; + } +}; + +#endif diff --git a/flower/lib/include/choleski.hh b/flower/lib/include/choleski.hh new file mode 100644 index 0000000000..f5e9fb4f5a --- /dev/null +++ b/flower/lib/include/choleski.hh @@ -0,0 +1,46 @@ +#ifndef CHOLESKI_HH +#define CHOLESKI_HH + +#include "matrix.hh" + +/** + Choleski decomposition of a matrix + structure for using the LU decomposition of a positive definite matrix. + + #P# is split into + + LD transpose(L) + */ +struct Choleski_decomposition { + + /// lower triangle of Choleski decomposition + Matrix L; + + /// diagonal + Vector D; + + /** Create decomposition of P. + PRE + P needs to be symmetric positive definite + */ + + Choleski_decomposition(Matrix P); + + /** + solve Px = rhs + */ + Vector solve(Vector rhs) const; + + Vector operator * (Vector rhs) const { return solve (rhs); } + /** + return the inverse of the matrix P. + */ + Matrix inverse() const; + /** + return P, calc'ed from L and D + */ + Matrix original() const; + + +}; +#endif diff --git a/flower/lib/include/compare.hh b/flower/lib/include/compare.hh new file mode 100644 index 0000000000..203ba014e7 --- /dev/null +++ b/flower/lib/include/compare.hh @@ -0,0 +1,55 @@ +/* + flowerlib + + (c) 1996 Han-Wen Nienhuys + */ +#ifndef COMPARE_HH +#define COMPARE_HH + +#define one_operator(type, function, op) \ +inline bool \ +operator op (type t1, type t2) {\ + return function(t1, t2) op 0;\ +}\ + +#define gpp_minmax_operator(type, op, opp) \ +inline type \ +operator op(type t1, type t2)\ +{\ + return (t1 opp t2) ? t1 : t2;\ +}\ + + +#if defined (__GNUG__) && ! defined (__STRICT_ANSI__) +#define gpp_minmax(type, prefix)\ + prefix gpp_minmax_operator(type, ?, >) +#else +#define gpp_minmax(type, prefix) +#endif + +/** handy notations for a signed comparison. + make the operators{<,<=,==,>=,>} and the MAX and MIN of two. + Please fill a & in the type argument if necessary. + */ +#define template_instantiate_compare(type, function, prefix) \ +prefix one_operator(type, function, >)\ +prefix one_operator(type, function, >=)\ +prefix one_operator(type, function, ==)\ +prefix one_operator(type, function, !=)\ +prefix one_operator(type, function, <)\ +prefix one_operator(type, function, <=)\ +gpp_minmax(type, prefix)\ +prefix inline type max(type t1, type t2) { return (t1 > t2 )? t1 : t2; }\ +prefix inline type min(type t1, type t2) { return (t1 < t2 )? t1 : t2; }\ + \ +prefix bool operator<(type t1, type t2) /* stupid fix to allow ; */ + + + +#define instantiate_compare(type, func) template_instantiate_compare(type,func, ) + + + +#endif + diff --git a/flower/lib/include/cursor.hh b/flower/lib/include/cursor.hh new file mode 100644 index 0000000000..0ea99037f9 --- /dev/null +++ b/flower/lib/include/cursor.hh @@ -0,0 +1,113 @@ +// cursor.hh + +#ifndef __CURSOR_HH +#define __CURSOR_HH + +#include "link.hh" +template class List; + +/** iterator to List. + add and insert extend the list + items are always stored as copies in List, but: + List : copies of String stored + List : copies of String* stored! + + the operations add and insert actually delegate the work to List class. + */ +template +class Cursor +{ + public: + /** create cursor, set at top. The const part isn't true, actually, #list# + surely isn't const, but I get tired of the warning messages. */ + Cursor( const List& list, Link* pointer = 0 ); + + Cursor( const Cursor& cursor ); + + T& thing(); + + /// return current T + T& operator *() { return thing(); } + operator T() { return thing(); } + Cursor operator =( const Cursor& c ); + + /// make cursor with #no# items back + Cursor operator -( int no) const; + + /// make cursor with #no# items further + Cursor operator +( int no) const; + int operator -(Cursor op) const; + Cursor operator -=(int); + Cursor operator +=(int); + + /// return current and move one down + Cursor operator ++( int ); + + /// return current and move one up + Cursor operator --( int ); + + /// point to link? + bool ok(); + + /// ++ items left? + bool forward(); + + /// -- items left? + bool backward(); + + /** put (copy) after me in List. + analogously to editor. ok() interpreted as at end + of line. + + PRE: !ok, POST: added to bottom() + + PRE: ok, POST: added after me + + cursor points to same object, cursor.next() is newly added + object. + */ + void add( const T& thing ); + + /** put (copy) before me in List. + analogously to editor. ok() interpreted as at begin of + line. + + PRE: !ok, POST: add to top() + + PRE: ok, POST: add before me + + cursor points to same object, cursor.previous() + is newly inserted object. + */ + + void insert( const T& thing ); + /// + void backspace(); + + /// + void del(); + + /// access the list this came from + List& list() const ; + Link* pointer(); + static int compare(Cursor a,Cursorb) { return a-b; } +private: + List& list_; + Link* pointer_; +}; + + +/* + comparisons. + */ +#include "compare.hh" + + +template_instantiate_compare(Cursor, Cursor::compare, template); + +#include "pcursor.hh" +#include "list.hh" +#include "cursor.inl" +#include "iterate.hh" + +#endif // CURSOR_HH diff --git a/flower/lib/include/cursor.inl b/flower/lib/include/cursor.inl new file mode 100644 index 0000000000..54d3703e60 --- /dev/null +++ b/flower/lib/include/cursor.inl @@ -0,0 +1,113 @@ + // cursor.inl -*-c++-*- +#ifndef CURSOR_INL +#define CURSOR_INL +#include + + +template +inline +Cursor::Cursor( const List& list, Link* pointer ) : + list_((List&) list ) +{ + if ( list.size() ) + pointer_ = pointer ? pointer : list.top_; + else + pointer_ = pointer; +} + +template +inline +Cursor::Cursor( const Cursor& cursor ) : + list_( cursor.list_ ) +{ + pointer_ = cursor.pointer_; +} + +template +inline T& +Cursor::thing() +{ + assert( pointer_ ); + return pointer_->thing(); +} + +template +Cursor +Cursor::operator =( const Cursor& c ) +{ + assert( &list_ == &c.list_ ); + pointer_ = c.pointer_; + return *this; +} + +template +inline void +Cursor::add( const T& th ) +{ + list_.add( th, *this ); +} + +template +inline void +Cursor::insert( const T& th ) +{ + list_.insert( th, *this ); +} + +template +inline List& +Cursor::list() const +{ + return list_; +} + +template +inline Link* +Cursor::pointer() +{ + return pointer_; +} + +template +inline bool +Cursor::backward() +{ + return ( pointer_ != 0 ); +} + +template +inline bool +Cursor::forward() +{ + return ( pointer_ != 0 ); +} + +template +inline bool +Cursor::ok() +{ + return ( pointer_ != 0 ); +} + + +template +inline Cursor +Cursor::operator ++( int ) +{ + Cursor r (*this); + assert( pointer_ ); + pointer_ = pointer_->next(); + return r; +} + +template +inline Cursor +Cursor::operator --( int ) +{ + Cursor r (*this); + assert( pointer_ ); + pointer_ = pointer_->previous(); + return r; +} + +#endif diff --git a/flower/lib/include/cursor.tcc b/flower/lib/include/cursor.tcc new file mode 100644 index 0000000000..3be73fe5d2 --- /dev/null +++ b/flower/lib/include/cursor.tcc @@ -0,0 +1,109 @@ +#ifndef CURSOR_CC +#define CURSOR_CC + +#include "cursor.hh" +#include + +template + void +Cursor::backspace() +{ + Cursor c(*this); + if ( c.ok() ) + c--; + list_.remove( *this ); +} + +template + void +Cursor::del() +{ + Cursor c(*this); + if ( c.ok() ) + c++; + list_.remove( *this ); + *this = c; +} + + +template +Cursor +Cursor::operator -=( int j ) +{ + while (j--) + (*this)--; + return *this; +} +template +Cursor +Cursor::operator +=( int j ) +{ + while (j++) + (*this)++; + return *this; +} + +template +Cursor +Cursor::operator +( int i ) const +{ + Cursor r = *this; + + if (i<0) + return r -(-i); + + while (i--) + r++; + + return r; +} + +template +Cursor +Cursor::operator -( int i ) const +{ + Cursor r = *this; + if (i<0) + return r +(-i); + + while (i--) + r--; + + return r; +} +/* + warning: can't use Cursor::operator == (Cursor), + since it uses Cursor::operator-(Cursor) + */ +template +int +Cursor::operator-(Cursor rhs) const +{ + assert(rhs.list == list); + int dif = 0; + + // search from *this on further up (positive difference) + Cursor c(*this); + while (c.ok() && c.pointer_ != rhs.pointer_) { + c--; + dif++; + } + + if (c.ok()) + goto gotcha; // so, sue me. + + // search in direction of bottom. (negative diff) + dif =0; + c=*this; + while (c.ok() && c.pointer_ !=rhs.pointer_) { + dif --; + c++; + } + assert(c.ok()); + +gotcha: + assert((*this - dif).pointer_ == c.pointer_); + return dif; +} + +#endif diff --git a/flower/lib/include/data-file.hh b/flower/lib/include/data-file.hh new file mode 100644 index 0000000000..dae9e56347 --- /dev/null +++ b/flower/lib/include/data-file.hh @@ -0,0 +1,59 @@ +/* + data-file.hh -- declare Data_file + + source file of the LilyPond music typesetter + + (c) 1997 Han-Wen Nienhuys +*/ + + +#ifndef DATAFILE_HH +#define DATAFILE_HH + +#include "text-stream.hh" + +/// read a data file +class Data_file : private Text_stream +{ + + public: + bool rawmode; + + Text_stream::line; + Text_stream::eof; + Text_stream::get_name; + + char data_get(); + void data_unget(char c) { + unget(c); + } + + /// read line, eat #\n# + String get_line(); + + /// read a word till next space, leave space. Also does quotes + String get_word(); + + /// gobble horizontal white stuff. + void gobble_white(); + + /// gobble empty stuff before first field. + void gobble_leading_white(); + Data_file(String s) : Text_stream(s) { + //*mlog << "(" << s << flush; + rawmode= false; + } + + ~Data_file() { + // *mlog << ")"< +struct Assoc; + +/** debug stream. + a class for providing debug output of nested structures, + with indents according to \{\}()[]. + + One can turn on and off specific messages using the Assoc silent. + This can be done automatically: + + #define DEBUG dstream_.identify_as(__PRETTY_FUNCTION__) + + DEBUG << "a message\n"; + + Init for the class names which should be silent can be given in a rc file. + + */ +class Dstream +{ + ostream *os; + int indentlvl; + bool local_silence; + String classname; + void output(String s); + Assoc *silent; +public: + + bool silence(String); + + /** + if rcfile == 0, then do not read any rc file. + */ + + Dstream(ostream *r, const char * rcfile); + virtual ~Dstream(); + Dstream &identify_as(String s); + + Dstream &operator << (String s); + /** + Output memory locations. + */ + Dstream &operator << (void const *); + Dstream &operator << (char const *); +}; +#endif + diff --git a/flower/lib/include/flower-config.hh b/flower/lib/include/flower-config.hh new file mode 100644 index 0000000000..e69de29bb2 diff --git a/flower/lib/include/fproto.hh b/flower/lib/include/fproto.hh new file mode 100644 index 0000000000..8c6fda680e --- /dev/null +++ b/flower/lib/include/fproto.hh @@ -0,0 +1,44 @@ +/* + fproto.hh -- typenames in flowerlib + + (c) 1996 Han-Wen Nienhuys +*/ + +#ifndef FPROTO_HH +#define FPROTO_HH + +#include "flower-config.hh" + +template struct Array; +template struct sstack; +template struct Assoc; +template struct List; +template struct PointerList; +template struct IPointerList; +template struct Cursor; +template struct PCursor; +template struct Link; +template struct Handle; +templatestruct Interval_t; +#include "real.hh" + +typedef Interval_t Interval; + +struct Choleski_decomposition; + +struct Long_option_init; +struct Getopt_long; +struct Matrix; +struct String_data; +struct String_handle; +struct String_convert; +struct String; +struct virtual_smat; +struct Vector ; +struct Text_stream; +struct Data_file; +struct Text_db; +struct Scalar; +typedef unsigned char Byte; +#endif // FPROTO_HH + diff --git a/flower/lib/include/handle.hh b/flower/lib/include/handle.hh new file mode 100644 index 0000000000..63c17ef1d2 --- /dev/null +++ b/flower/lib/include/handle.hh @@ -0,0 +1,58 @@ +#ifndef HANDLE_HH +#define HANDLE_HH + +/// reference counting handle +template +class Handle { + T *obj; + int *refs; + + /// let go of ref. Delete if necessary + void down() { + if (!(*refs--)) { + delete obj; + delete refs; + } + obj = 0; + refs = 0; + } + /// point to new object. + void up(T *t, int *r) { + if (!r) { + refs = new int; + *refs = 1; + } else { + refs =r; + *refs++; + } + obj = t; + } + /// POST: *refs == 1 + void copy() { + if(*refs != 1){ + T * newobj = new T(*obj ); + down(); + up(newobj); + } + } + Handle(Handle const &src) { + up(src.obj, src.refs); + } + Handle(T & o) { + up (&o); + } + void operator=(Handle const& src) { + if (this == &src) + return; + down(); + up(src.o, src.refs); + } + operator const T&() { + return *obj; + } + operator T&() { + copy(); + return *obj; + } +} +#endif diff --git a/flower/lib/include/interval.hh b/flower/lib/include/interval.hh new file mode 100644 index 0000000000..aae16381db --- /dev/null +++ b/flower/lib/include/interval.hh @@ -0,0 +1,125 @@ +/* + interval.hh -- part of flowerlib + + (c) 1996 Han-Wen Nienhuys +*/ + +#ifndef INTERVAL_HH +#define INTERVAL_HH + +#include +#include "fproto.hh" +#include "real.hh" + + +/** a T interval. + this represents the closed interval [left,right]. + No invariants. T must be a totally ordered ring + */ +template +struct Interval_t { + T left, right; + + /* ************** */ + + T center() { return (left + right) / T(2);} + void translate(T t) { + left += t; + right += t; + } + T& idx(int j) { + if (j==-1) + return left; + else if (j==1) + return right; + else + assert(false); + return left; + } + T& operator[](int j) { + return idx(j); + } + T operator[](int j) const { + return ((Interval_t *)this)->idx(j); + } + T &max() { return right;} + T max()const { return right;} + T min()const{ return left; } + T &min(){ return left; } + /** + PRE + *this and h are comparable + */ + void unite(Interval_t h); + void intersect(Interval_t h); + + T length() const; + void set_empty() ; + bool empty() const { return left > right; } + Interval_t() { + set_empty(); + } + Interval_t(T m, T M) { + left =m; + right = M; + } + Interval_t &operator += (T r) { + left += r; + right +=r; + return *this; + } + String str() const; + bool elt_q(T r); +}; + + +/** + inclusion ordering. Crash if not comparable. + */ +template +int Interval__compare(const Interval_t&,Interval_t const&); + +/* + INLINE + */ + +#include "compare.hh" + +template_instantiate_compare(Interval_t&, Interval__compare, template); + + +template +inline Interval_t +intersection(Interval_t a, Interval_t const&b) +{ + a.intersect(b); + return a; + +} + + +template +inline +Interval_t operator +(T a,Interval_t i ) +{ + i += a; + return i; +} + +template +inline +Interval_t operator +(Interval_t i,T a ){ + return a+i; +} + +typedef Interval_t Interval; + + +#define Interval__instantiate(T) template struct Interval_t;\ + template int Interval__compare(const Interval_t&,Interval_t const&) + + +#endif // INTERVAL_HH + + + diff --git a/flower/lib/include/interval.tcc b/flower/lib/include/interval.tcc new file mode 100644 index 0000000000..6e7b0b1279 --- /dev/null +++ b/flower/lib/include/interval.tcc @@ -0,0 +1,106 @@ +#include +#include +#include "interval.hh" +#include "string.hh" + + +template +int +_Interval__compare(const Interval_t&a,Interval_t const&b) +{ + if (a.left == b.left && a.right == b.right) + return 0; + + if (a.left <= b.left && a.right >= b.right) + return 1; + + if (a.left >= b.left && a.right <= b.right) + return -1; + + return -2; +} + + +template +int +Interval__compare(const Interval_t&a,Interval_t const&b) +{ + int i = _Interval__compare(a,b); + if (i < -1) + assert(false); + return i; +} + +#ifdef AIX +const Real INFTY = 1e8; // ARGh. AIX sucks +#else +const Real INFTY = HUGE_VAL; +#endif + +template +void +Interval_t::set_empty() +{ + left = INFTY; + right = -INFTY; +} + +template +T +Interval_t::length() const { + assert(right >= left); + return right-left; +} + +template +void +Interval_t::unite(Interval_t h) +{ + if (h.leftright) + right = h.right; +} + +/** + smallest Interval which includes *this and #h# + */ + +template +void +Interval_t::intersect(Interval_t h) +{ +#if defined (__GNUG__) && ! defined (__STRICT_ANSI__) + left = h.left >? left; + right = h.right +Interval_t +intersect(Interval_t x, Interval_t const &y) +{ + x.intersect(y); + return x; +} + +template +String +Interval_t::str() const +{ + if (empty()) + return "[empty]"; + String s("["); + + return s + left + "," + right +"]"; +} + +template +bool +Interval_t::elt_q(T r) +{ + return r >= left && r <= right; +} diff --git a/flower/lib/include/iterate.hh b/flower/lib/include/iterate.hh new file mode 100644 index 0000000000..1e924f0790 --- /dev/null +++ b/flower/lib/include/iterate.hh @@ -0,0 +1,22 @@ +/* + iterate.hh -- define some list macros + + source file of the flowerlib + + (c) 1997 Han-Wen Nienhuys +*/ + + +#ifndef ITERATE_HH +#define ITERATE_HH + + + +#define iterator(set) typeof((set).top()) +#define iterator_bot(set) typeof((set).bottom()) + +// should use top() +#define iter_top(set,var) iterator(set) var(set) +#define iter_bot(set,var) iterator(set) var(set.bottom()) + +#endif // ITERATE_HH diff --git a/flower/lib/include/lgetopt.hh b/flower/lib/include/lgetopt.hh new file mode 100644 index 0000000000..3b2b0348b3 --- /dev/null +++ b/flower/lib/include/lgetopt.hh @@ -0,0 +1,94 @@ +#ifndef LGETOPT_HH +#define LGETOPT_HH + +#include + + +class ostream; + +/** + a struct this for initialising the commandline options. + */ +struct Long_option_init { + bool take_arg; + const char* longname; + char shortname; + + ostream &printon(ostream &errorout); +}; + + +/** C++ for version of long_getopt. For processing GNU style command + line arguments. No pointer (return values, arguments) contents are + copied. */ +class Getopt_long { +public: + /** errorcodes: no error, argument expected, no argument expected, + unknown option, illegal argument (eg. int expected). */ + enum Errorcod { E_NOERROR = 0, E_ARGEXPECT, E_NOARGEXPECT, E_UNKNOWNOPTION, + E_ILLEGALARG } ; + + +private: + + /// the option info. + Long_option_init *the_opts; + int table_len; + + /// if doing short option, argv[optind][optindind] is processed next. + int optindind; + + /// the option found + Long_option_init *beet; + + /// get ready for processing next error. + bool next(); + Long_option_init *parselong(); + Long_option_init *parseshort(); + + ostream *errorout; + + /// report an error and abort + void report(Errorcod c); +public: + + /// argument. Set to 0 if not present + char* optarg; + + /// current error status + Errorcod error; + + /// return an integer (with err. detect) + long intarg(); + /// argv[optind] will be processed next. + int optind; + + /// the arguments + char **argv; + + /// the arg. count + int argc; + + /* *************** */ + + /** + What to do with errors. + report messages on #*os#, and abort. + if #os# is null, then do not report nor abort, just set #error# + */ + + void seterror(ostream *os); + + /// construct: pass arguments and option info. + Getopt_long(int c, char **v, Long_option_init *lo); + + /** get the next option. + @return pointer to next option found. + 0 if error occurred, or next argument is no option. + */ + Long_option_init *operator()(); + + char *current_arg(); + char * get_next_arg(); +}; +#endif diff --git a/flower/lib/include/libc-extension.hh b/flower/lib/include/libc-extension.hh new file mode 100644 index 0000000000..e71037c41e --- /dev/null +++ b/flower/lib/include/libc-extension.hh @@ -0,0 +1,32 @@ +/* + libc-extension.hh -- declare some string.h extensions + + source file of the flowerlib + + (c) 1997 Han-Wen Nienhuys +*/ + + +#ifndef LIBC_EXTENSION_HH +#define LIBC_EXTENSION_HH +#include "fproto.hh" + +char* strnlwr( char* start_l ,int n); +char* strnupr( char* start_l, int n); + +#ifndef HAVE_MEMMEM // GNU extension. +char *memmem(const Byte * haystack, int haystack_len, + const Byte *needle, int needle_len); +#endif HAVE_MEMMEM + +#ifndef HAVE_SNPRINTF // GNU extension. +int snprintf (char *str, size_t n, + const char *format, ... ); +#endif + + +Byte *memrchr(const Byte * p, int n, char c); +Byte *strrev( Byte* byte_l, int length_i ); + + +#endif // LIBC_EXTENSION_HH diff --git a/flower/lib/include/link.hh b/flower/lib/include/link.hh new file mode 100644 index 0000000000..6f9c75a411 --- /dev/null +++ b/flower/lib/include/link.hh @@ -0,0 +1,38 @@ +// link.hh + +#ifndef __LINK_HH +#define __LINK_HH +template +class List; + + +/// class for List +template +class Link +{ +// friend class Cursor; +public: + Link( const T& thing ); + + Link* previous(); + Link* next(); + + /// put new Link item after me in list + void add( const T& thing ); + /// put new Link item before me in list + void insert( const T& thing ); + void remove(List &l); + + T& thing(); + void OK() const; +private: + Link( Link* previous, Link* next, const T& thing ); + + T thing_; + Link* previous_; + Link* next_; +}; + +#include "link.inl" + +#endif // __LINK_HH // diff --git a/flower/lib/include/link.inl b/flower/lib/include/link.inl new file mode 100644 index 0000000000..3926d6bc2a --- /dev/null +++ b/flower/lib/include/link.inl @@ -0,0 +1,102 @@ +// link.inl -*-c++-*- +#ifndef LINK_INL +#define LINK_INL +#include +template +inline +void +Link::OK() const +{ +#ifndef NDEBUG + if (previous_) { + assert(previous_->next_ == this); + } + if (next_) { + assert(next_->previous_ == this); + } +#endif +} + +template +inline +Link::Link( const T& thing ) : + thing_( thing ) +{ + previous_ = next_ = 0; +} + +template +inline +Link::Link( Link* previous, Link* next, const T& thing ) : + thing_( thing ) +{ + previous_ = previous; + next_ = next; +} + +template +inline +Link* +Link::next() +{ + return next_; +} + +template +inline +Link* +Link::previous() +{ + return previous_; +} + +template +inline +void +Link::add( const T& thing ) +{ + + Link* l = new Link( this, next_, thing ); + if ( next_ ) + next_->previous_ = l; + next_ = l; +} + +template +inline void +Link::insert( const T& thing ) +{ + // Link* l = new Link( next_, this, thing ); + // bugfix hwn 16/9/96 + Link* l = new Link( previous_, this, thing ); + if ( previous_ ) + previous_->next_ = l; + previous_ = l; +} + +/* + don't forget to adjust #l#'s top_ and bottom_. + */ +template +inline void +Link::remove(List &l) +{ + if ( previous_ ) + previous_->next_ = next_; + else + l.top_ = next_; + + if ( next_ ) + next_->previous_ = previous_; + else + l.bottom_ = previous_; +} + +template +inline +T& +Link::thing() +{ + return thing_; +} +#endif diff --git a/flower/lib/include/list.hh b/flower/lib/include/list.hh new file mode 100644 index 0000000000..ec59fbff07 --- /dev/null +++ b/flower/lib/include/list.hh @@ -0,0 +1,98 @@ +#ifndef __LIST_HH +#define __LIST_HH + +class ostream; +template class Cursor; +template class Link; + +/** all-purpose doubly linked list. + + List can be seen as all items written down on paper, + from top to bottom + + class Cursor is used to extend List + + items are always stored as copies in List, but: + #List# : copies of #String# stored + #List# : copies of #String*# stored! + (do not use, use \Ref{PointerList} ## instead.) + + {\bf note:} + retrieving "invalid" cursors, i.e. + #top()/bottom()# from empty list, #find()# without success, + results in a nonvalid Cursor ( #!ok()# ) + + + INVARIANTEN! +*/ + +template +class List +{ + public: + List(List const&src); + + /// construct empty list + List(); + virtual ~List(); + + int size() const; + + Cursor bottom() const; // const sucks. + Cursor top() const; + + void OK() const; // check list + + protected: + friend class Cursor; + friend class Link; + + void concatenate(List const &s); + + /** make *this empty. + + POST: + size == 0 + + WARNING: + contents lost, and not deleted. + */ + void set_empty(); + + void add( const T& thing, Cursor &after_me ); + + /// put thing before #before_me# + void insert( const T& thing, Cursor &before_me ); + + /** Remove link pointed to by me. Destructor of contents called + (nop for pointers) + + POST + none; + + + WARNING: do not use #me# after calling + */ + void remove( Cursor me ); + + + /* ************** */ + + int size_; + Link* top_; + Link* bottom_; +}; + +#include "list.inl" +#include "cursor.hh" + +// instantiate a template: explicit instantiation. +#define L_instantiate(a) template class List; template class Cursor; \ + template class Link + + +#endif // __LIST_HH // + + + + diff --git a/flower/lib/include/list.inl b/flower/lib/include/list.inl new file mode 100644 index 0000000000..df0687b7c8 --- /dev/null +++ b/flower/lib/include/list.inl @@ -0,0 +1,56 @@ +// -*-c++-*- + +#ifndef LIST_INL +#define LIST_INL + +template +inline +List::List() +{ + set_empty(); +} + +template +inline void +List::set_empty() +{ + top_ = bottom_ = 0; + size_ = 0; +} + +template +inline void +List::remove( Cursor me ) +{ + if ( me.ok() ){ + Link *lp = me.pointer(); + lp->remove(*this); + delete lp; + size_--; + } +} + +template +inline int +List::size() const +{ + return size_; +} + +template +inline Cursor +List::top()const +{ + return Cursor( *this, top_ ); +} + + +template +inline Cursor +List::bottom()const +{ + return Cursor( *this, bottom_ ); +} + + +#endif diff --git a/flower/lib/include/list.tcc b/flower/lib/include/list.tcc new file mode 100644 index 0000000000..16e12a31f1 --- /dev/null +++ b/flower/lib/include/list.tcc @@ -0,0 +1,112 @@ +#ifndef LIST_CC +#define LIST_CC + +#include "list.hh" + +template +List::List(List const&src) +{ + set_empty(); + // probably el stupido + for (Cursor c(src); c.ok(); c++) + bottom().add(c); +} + +template +void +List::OK() const +{ + int i = size_; + Link *lp = top_; + while (i--) { + assert(lp); + lp->OK(); + lp = lp->next(); + } + assert(!lp); + i = size_; + lp = bottom_; + while (i--) { + assert(lp); + lp->OK(); + lp = lp->previous(); + } + assert(!lp); +} + + +template +List::~List() +{ + Cursor c(*this); + while (c.ok()) + c.del(); +} + +/** + + add after after_me. + + Procedure: + \begin{itemize} + \item if #after_me# is #ok()#, add after #after_me#, else + \item if list !empty simply add to bottom, else + \item list is empty: create first \Ref{Link} and initialize + #bottom_# and #top_#. + \end{itemize} +*/ +template +void +List::add( const T& thing, Cursor &after_me ) +{ + if (!size_) { // not much choice if list is empty + bottom_ = top_ = new Link( thing ); + if (!after_me.ok()) + after_me = bottom(); + } else { // add at aprioprate place + if (!after_me.ok()) + after_me = bottom(); + Link *p =after_me.pointer(); + p->add(thing); + if (p == bottom_) // adjust bottom_ if necessary. + bottom_ = p->next(); + } + + size_++; +} + +template +void +List::insert( const T& thing, Cursor &before_me ) +{ + if (!size_) { + bottom_ = top_ = new Link( thing ); + if (!before_me.ok()) + before_me = top(); + + } else { + if (!before_me.ok()) + before_me = top(); + + Link *p = before_me.pointer() ; + + p->insert(thing); + if (p == top_) + top_ = p->previous(); + } + + size_++; +} + + +template +void +List::concatenate(List const&s) +{ + Cursor b(bottom()); + for (Cursor c(s); c.ok(); c++) { + b.add(c); + b++; + } +} +#endif diff --git a/flower/lib/include/matrix.hh b/flower/lib/include/matrix.hh new file mode 100644 index 0000000000..a633d6657a --- /dev/null +++ b/flower/lib/include/matrix.hh @@ -0,0 +1,135 @@ +#ifndef MATRIX_HH +#define MATRIX_HH + + +#include "vsmat.hh" +#include "vector.hh" + +/** a Real matrix. This is a class for a nonsquare block of #Real#s. The + implementation of sparse matrices is done in the appropriate #smat# + class. Matrix only does the mathematical actions (adding, + multiplying, etc.) + + + TODO + implement ref counting? */ + + +class Matrix { + virtual_smat *dat; + +public: + void OK() const { dat->OK(); } + int cols() const { return dat->cols(); } + int rows() const { return dat->rows(); } + + /** return the size of a matrix. + PRE + the matrix needs to be square. + */ + int dim() const; + + // Matrix() { dat = 0; } + ~Matrix() { delete dat; } + + /// set entries to r + void fill(Real r); + + /// set diagonal to d + void set_diag(Real d); + + void set_diag(Vector d); + /// set unit matrix + void unit() { set_diag(1.0); } + + void operator+=(const Matrix&m); + void operator-=(const Matrix&m); + void operator*=(Real a); + void operator/=(Real a) { (*this) *= 1/a; } + + /** add a row. + add a row to the matrix before row k + + PRE + v.dim() == cols() + 0 <= k <= rows() + */ + void insert_row(Vector v,int k); + /** . + delete a row from this matrix. + + PRE + 0 <= k < rows(); + */ + void delete_row(int k) { dat->delete_row(k); } + void delete_column(int k) { dat->delete_column(k); } + + /** + square n matrix, initialised to null + */ + Matrix(int n); + + /** + n x m matrix, init to 0 + */ + Matrix(int n, int m); + Matrix(const Matrix &m); + + /// dyadic product: v * w.transpose + Matrix(Vector v, Vector w); + void operator=(const Matrix&m); + + /// access an element + Real operator()(int i,int j) const { return dat->elem(i,j); } + + /// access an element + Real &operator()(int i, int j) { return dat->elem(i,j); } + + /// Matrix multiply with vec (from right) + Vector operator *(const Vector &v) const; + + /// set this to m1*m2. + void set_product(const Matrix &m1, const Matrix &m2); + + + Vector left_multiply(Vector const &) const; + + Matrix operator-() const; + + /// transpose this. + void transpose(); + + /// return a transposed copy. + Matrix transposed() const ; + + Real norm() const; + /** swap. + PRE + 0 <= c1,c2 < cols() + */ + void swap_columns(int c1, int c2); + + /** swap. + PRE + 0 <= c1,c2 < rows() + */ + void swap_rows(int c1, int c2); + + + Vector row(int ) const; + Vector col(int) const; + + operator String() const; + void print() const; +}; + +inline Vector +operator *(Vector &v, const Matrix& m) { return m.left_multiply(v); } +Matrix operator *(const Matrix& m1,const Matrix &m2); +Matrix operator /(const Matrix &m1,Real a); +inline Matrix operator -(Matrix m1,const Matrix m2) +{ + m1 -= m2; + return m1; +} +#endif diff --git a/flower/lib/include/path.hh b/flower/lib/include/path.hh new file mode 100644 index 0000000000..bc4d9f3776 --- /dev/null +++ b/flower/lib/include/path.hh @@ -0,0 +1,32 @@ +#ifndef PATH_HH +#define PATH_HH +#include "string.hh" +#include "varray.hh" + + +/** searching directory for file. + + Abstraction of PATH variable. An interface for searching input files. + Search a number of dirs for a file. + + Should use kpathsea? + +*/ + +class File_path : private Array +{ +public: + /// locate a file in the search path + String find(String nm); + + /// construct using prefix. Normally argv[0]. + File_path(String); + + /// add to end of path. + Array::push; + void add(String str) { push(str); } +}; +/// split path into its components +void split_path(String path, String &drive, String &dirs, String &filebase, String &extension); + +#endif diff --git a/flower/lib/include/pcursor.tcc b/flower/lib/include/pcursor.tcc new file mode 100644 index 0000000000..ffb01bcfe8 --- /dev/null +++ b/flower/lib/include/pcursor.tcc @@ -0,0 +1,16 @@ +#include "pcursor.hh" + +template +void +PCursor::junk() +{ +#if !defined(NDEBUG) && defined(PARANOID) + list().OK(); +#endif + + delete ptr(); +#if !defined(NDEBUG)&&defined(PARANOID) + thing() = 0; + list().OK(); +#endif +} diff --git a/flower/lib/include/plist.tcc b/flower/lib/include/plist.tcc new file mode 100644 index 0000000000..ac9daedf71 --- /dev/null +++ b/flower/lib/include/plist.tcc @@ -0,0 +1,21 @@ +#include "plist.hh" + +template +IPointerList::~IPointerList() +{ + PCursor c( *this ); + while (c.ok()) { + delete c.remove_p(); + } +} + +template +PCursor +PointerList::find(T what ) const +{ + PCursor i(*this); + for (; i.ok(); i++) + if (i.ptr() == what) + break; + return i; +} diff --git a/flower/lib/include/pqueue.hh b/flower/lib/include/pqueue.hh new file mode 100644 index 0000000000..195232317e --- /dev/null +++ b/flower/lib/include/pqueue.hh @@ -0,0 +1,46 @@ +/* + pqueue.hh -- declare + + source file of the LilyPond music typesetter + + (c) 1997 Han-Wen Nienhuys +*/ + + +#ifndef PQUEUE_HH +#define PQUEUE_HH + +#include "varray.hh" + +/** + Stupid Prioq. Should use Lists and STL. + Smallest is put at the front. + */ + +template +struct PQueue +{ + Array value_arr_; + Array indices_arr_; + + void enter(V v, I idx) { + int j=0; + for (; j < value_arr_.size(); j++) + if (indices_arr_[j] > idx) + break; + + value_arr_.insert(v, j); + indices_arr_.insert(idx, j); + } + int size() { return value_arr_.size(); } + V front_val() { return value_arr_[0]; } + I front_idx() { return indices_arr_[0]; } + V get() { + V retval = front_val(); + value_arr_.del(0); + indices_arr_.del(0); + return retval; + } + +}; +#endif // PQUEUE_HH diff --git a/flower/lib/include/rational.hh b/flower/lib/include/rational.hh new file mode 100644 index 0000000000..30fa2cb6d6 --- /dev/null +++ b/flower/lib/include/rational.hh @@ -0,0 +1 @@ +#include diff --git a/flower/lib/include/real.hh b/flower/lib/include/real.hh new file mode 100644 index 0000000000..0533af2111 --- /dev/null +++ b/flower/lib/include/real.hh @@ -0,0 +1,16 @@ +#ifndef REAL_HH +#define REAL_HH + + +#include +#include +#include + +typedef double Real; + +inline Real +distance(Real x,Real y) +{ + return abs(x-y); +} +#endif diff --git a/flower/lib/include/scalar.hh b/flower/lib/include/scalar.hh new file mode 100644 index 0000000000..5cdfa427da --- /dev/null +++ b/flower/lib/include/scalar.hh @@ -0,0 +1,34 @@ +/* + scalar.hh -- part of LilyPond + + (c) 1996 Han-Wen Nienhuys +*/ + +#ifndef SCALAR_HH +#define SCALAR_HH +#include "string.hh" +#include "real.hh" + +/// Perl -like scalar type. +struct Scalar : public String { + + Scalar(Real r) : String(r) {} + Scalar(int i) : String(i) {} + Scalar(char c) : String(c) {} + Scalar(const char *c) : String(c) {} + Scalar(String s ):String(s) {} + Scalar(Rational ); + operator Rational(); + Scalar() {} + bool isnum(); + operator Real(); + operator int(); + + /** perl -like string to bool conversion. + */ + operator bool() const; + +}; + +#endif // SCALAR_HH + diff --git a/flower/lib/include/smat.hh b/flower/lib/include/smat.hh new file mode 100644 index 0000000000..9b0987c8f4 --- /dev/null +++ b/flower/lib/include/smat.hh @@ -0,0 +1,93 @@ +#ifndef SMAT_HH +#define SMAT_HH +#include "varray.hh" +#include "vsmat.hh" +#include "real.hh" +/// simplest matrix storage. refer to its baseclass for the doco. +class Full_storage : public virtual_smat +{ + /// height, width + int h,w; + /// maxima. + int maxh, maxw; + + /// the storage + Real** els; + void + init() { + els=0; + h=w=maxh=maxw=0; + + } + + bool valid(int i, int j) const { + return (i>=0 && i < h) + && (j < w && j >=0); + } + + + void resize_rows(int); + void resize_cols(int); + +public: + virtual int rows() const { + return h; + } + virtual int cols() const { + return w; + } + + + virtual void set_size(int i, int j) + { + resize(i,j); //this could be more efficient. + } + + virtual void set_size(int i) { + set_size(i,i); + } + virtual void resize(int i, int j); + virtual void resize(int i) { + resize(i,i); + } + + virtual Real& elem(int i,int j) { + assert(valid(i,j)); + return els[i][j]; + } + virtual const Real& elem(int i, int j) const { + assert(valid(i,j)); + return els[i][j]; + } + virtual Array row(int i) const; + virtual Array column(int j) const; + + Full_storage() { + init(); + } + Full_storage(int i, int j) { + init(); + set_size(i,j); + } + Full_storage(Full_storage&); + Full_storage(int i) { + init(); + set_size(i); + } + void OK() const; + void operator=(Full_storage const &); + + virtual void insert_row(int k); + virtual void delete_row(int k); + virtual void delete_column(int k); + + + ~Full_storage(); + virtual bool mult_ok(int i, int j)const; + virtual void mult_next(int &i, int &j) const ; + virtual bool trans_ok(int i, int j) const; + virtual void trans_next(int &i, int &j) const; + virtual virtual_smat * clone(); +}; + +#endif diff --git a/flower/lib/include/string-convert.hh b/flower/lib/include/string-convert.hh new file mode 100644 index 0000000000..bcf461f8f3 --- /dev/null +++ b/flower/lib/include/string-convert.hh @@ -0,0 +1,43 @@ +/* + PROJECT: FlowerSoft C++ library + FILE : string-convert.hh + +*/ + +#ifndef STRING_CONVERT_HH +#define STRING_CONVERT_HH + +/* + ///a class which only has functions. +//#define functor class // cute. docxx fucks up +*/ + +/** + The functor String_convert handles all conversions to/from String (some + time, anyway). + The class is quite empty from data view. + */ +class String_convert { + static int hex2bin_i( String hex_str, String& bin_str_r ); + static int hex2nibble_i( Byte byte ); + static Byte nibble2hex_byte( Byte byte ); +public: + static String bin2dec_str( String bin_str ); + static String bin2hex_str( String bin_str ); + static String dec2bin_str( String str ); + static int bin2_i( String str ); + static String char_str(char c, int n); + static int dec2_i( String dec_str ); + static double dec2_f( String dec_str ); + static String double_str(double f, char const* fmt=0); + static int hex2int_i( String str ); + static String hex2bin_str( String str ); + static String int_str(int i, char const *fmt=0 ); + static String i2hex_str( int i, int length_i, char ch ); + static String i2dec_str( int i, int length_i, char ch ); + static String rational_str(Rational); + static String pointer_str(const void *); + static String longlong_str(long long , char const * fmt = 0); +}; + +#endif // __STRING_CONVERT_HH // diff --git a/flower/lib/include/string-data.hh b/flower/lib/include/string-data.hh new file mode 100644 index 0000000000..ecd7159074 --- /dev/null +++ b/flower/lib/include/string-data.hh @@ -0,0 +1,95 @@ +/* + string-data.hh -- declare String_data + + source file of the LilyPond music typesetter + + (c) 1997 Han-Wen Nienhuys +*/ + + +#ifndef STRINGDATA_HH +#define STRINGDATA_HH + + +/**Internal String struct. + the data itself. Handles simple tasks (resizing, resetting) + */ +class String_data { + // GNU malloc: storage overhead is 8 bytes anyway. + +friend class String_handle; + int maxlen; // maxlen is arraysize-1 + + int length_i_; + Byte* data_byte_p_; + int references; + + /// init to "" + String_data(); + + /// init from src. Conservative allocation. + String_data(String_data const &src); + + ~String_data(); + + /** POST: maxlen >= j. + @param j, maximum stringlength_i_. + contents thrown away. + */ + void setmax(int j); + + /** POST: maxlen >= j. + @param j, maximum stringlength_i_. + contents are kept if it grows. + */ + void remax(int j); + + /// check if writeable. + void OKW(); + + /// check state. + void OK(); + + /// reduce memory usage. + void tighten(); + + // assignment. + void set( Byte const* byte_c_l, int length_i ); + + void set( char const* ch_c_l ); + + /// concatenation. + void append( Byte const* byte_c_l, int length_i ); + + void operator += ( char const* ch_c_l ); + + char const* ch_c_l() const; + + char* ch_l(); + + Byte const* byte_c_l() const; + + // idem, non const + Byte* byte_l(); + + void trunc(int j); + + /** access element. not really safe. Can alter length_i_ without + #String_data# knowing it. */ + Byte &operator [](int j); + Byte operator [](int j) const; + bool is_binary_bo()const; +}; + + + +#ifdef STRING_UTILS_INLINED +#ifndef INLINE +#define INLINE inline +#endif +#include "string-data.inl" + +#endif + + +#endif // STRING_DATA_HH diff --git a/flower/lib/include/string-data.inl b/flower/lib/include/string-data.inl new file mode 100644 index 0000000000..d2b925d0ce --- /dev/null +++ b/flower/lib/include/string-data.inl @@ -0,0 +1,210 @@ +/* -*-C++-*- + String_data.inl -- implement String_data + + source file of Flower lib + + (c) 1997 Han-Wen Nienhuys +*/ + +#ifndef STRINGDATA_INL +#define STRINGDATA_INL + +#include +#include + +#include "string-data.hh" +const int INITIALMAX=8; + +#include + +INLINE void +String_data::OKW() +{ + assert (references == 1); +} + +INLINE void +String_data::OK() +{ + assert(maxlen >= length_i_); + assert(bool(data_byte_p_)); + assert(references >= 1); +} + + +INLINE +String_data::String_data() +{ + references=0; + maxlen = INITIALMAX; + data_byte_p_ = new Byte[maxlen + 1]; + data_byte_p_[0] = 0; + length_i_ = 0; +} + +INLINE +String_data::String_data(String_data const &src) +{ + references=0; + maxlen = length_i_ = src.length_i_; + data_byte_p_ = new Byte[maxlen+1]; // should calc GNU 8byte overhead. + memcpy( data_byte_p_, src.data_byte_p_, length_i_ + 1 ); +} + +INLINE +String_data::~String_data() +{ + assert(references == 0); + delete[] data_byte_p_; +} + +INLINE void +String_data::setmax(int j) +{ + OKW(); + if (j > maxlen) { + delete data_byte_p_; + maxlen = j; + data_byte_p_ = new Byte[maxlen + 1]; + + data_byte_p_[0] = 0; + length_i_ = 0; + } +} + +/* this is all quite hairy: + update of length_i_ + update of maxlen + alloc of buffer + copying of buffer + needs blondification: + split tasks + define change authority +*/ +INLINE void +String_data::remax(int j) +{ + OKW(); + if (j > maxlen) { + Byte *p = new Byte[j + 1]; + memcpy( p, data_byte_p_, ( maxlen = 0 && j <= length_i_); + data_byte_p_[j] = 0; + length_i_ = j; +} + +INLINE bool +String_data::is_binary_bo()const +{ +// return !memchr(data_byte_p_, length_i_, 0); + return ( (int)strlen( (char const*)data_byte_p_ ) != length_i_ ); +} + +INLINE Byte& +String_data::operator [](int j) +{ + assert(j >= 0 && j <= length_i_); + return data_byte_p_[j] ; +} + +INLINE Byte +String_data::operator [](int j) const +{ + assert(j >= 0 && j <= length_i_); + return data_byte_p_[j]; +} + + + + +#endif // __STRING_UTIL_CC // diff --git a/flower/lib/include/string-handle.hh b/flower/lib/include/string-handle.hh new file mode 100644 index 0000000000..5b7a12f648 --- /dev/null +++ b/flower/lib/include/string-handle.hh @@ -0,0 +1,70 @@ +/* + string-handle.hh -- declare String_handle + + source file of the LilyPond music typesetter + + (c) 1997 Han-Wen Nienhuys +*/ + + +#ifndef STRINGHANDLE_HH +#define STRINGHANDLE_HH +#include "fproto.hh" + + +/** + Reference counting for strings. + + handles ref. counting, and provides a very thin interface using + Byte * + + */ +class String_handle { + String_data* data; + + /// decrease ref count. Named kind of like a Tanenbaum semafore + void down(); + + /// increase ref count + void up(String_data *d); + + /** make sure data has only one reference. + POST: data->references == 1 + */ + void copy(); + +public: + String_handle(); + ~String_handle(); + String_handle(String_handle const & src); + + Byte const* byte_c_l() const; + char const* ch_c_l() const; + Byte* byte_l(); + char* ch_l(); + bool is_binary_bo()const; + void operator =(String_handle const &src); + void operator += (char const *s); + Byte operator[](int j) const; + + /** Access elements. WARNING: NOT SAFE + don't use this for loops. Use byte_c_l() + */ + Byte &operator[](int j); + void append( Byte const* byte_c_l, int length_i ); + void set( Byte const* byte_c_l, int length_i ); + void operator = (char const *p); + void trunc(int j); + int length_i() const; +}; + +#ifdef STRING_UTILS_INLINED +#ifndef INLINE +#define INLINE inline +#endif +#include "string-handle.inl" +/* we should be resetting INLINE. oh well. */ +#endif + + +#endif // STRINGHANDLE_HH diff --git a/flower/lib/include/string-handle.inl b/flower/lib/include/string-handle.inl new file mode 100644 index 0000000000..1f1d44ab13 --- /dev/null +++ b/flower/lib/include/string-handle.inl @@ -0,0 +1,156 @@ +/* -*-c++-*- + + stringhandle.inl -- implement String_handle + + source file of Flower lib + + (c) 1997 Han-Wen Nienhuys +*/ + +#ifndef STRINGHANDLE_INL +#define STRINGHANDLE_INL + +#include +#include + +#include "string-data.hh" +#include "string-handle.hh" + +INLINE void +String_handle::down() +{ + if (!(--data->references)) delete data; data = 0; +} + +/// increase ref count +INLINE void +String_handle::up(String_data *d) +{ + data=d; data->references ++; +} + +INLINE void +String_handle::copy() +{ + if (data->references !=1){ + String_data *newdata = new String_data(*data); + down(); + up(newdata); + } +} + +INLINE +String_handle::String_handle() +{ + up(new String_data); +} + +INLINE +String_handle::~String_handle() +{ + down(); +} + +INLINE +String_handle::String_handle(String_handle const & src) +{ + up(src.data); +} + +INLINE Byte* +String_handle::byte_l() +{ + copy(); + return data->byte_l(); +} + +INLINE char* +String_handle::ch_l() +{ + copy(); + return (char*)data->byte_l(); +} + +INLINE Byte +const* String_handle::byte_c_l() const +{ + return data->byte_c_l(); +} + +INLINE char const* +String_handle::ch_c_l() const +{ + return (char const*)data->byte_c_l(); +} + +INLINE void +String_handle::operator =(String_handle const &src) +{ + if (this == &src) + return; + down(); + up(src.data); +} + +INLINE void +String_handle::operator += (char const *s) +{ + copy(); + *data += s; +} + + +INLINE Byte +String_handle::operator[](int j) const +{ + return (*data)[j]; +} + +// !NOT SAFE! +// don't use this for loops. Use byte_c_l() +INLINE Byte & +String_handle::operator[](int j) +{ + copy(); // hmm. Not efficient + return data->byte_l()[j]; +} + +INLINE void +String_handle::append( Byte const* byte_c_l, int length_i ) +{ + copy(); + data->append( byte_c_l, length_i ); +} + +INLINE void +String_handle::set( Byte const* byte_c_l, int length_i ) +{ + copy(); + data->set( byte_c_l, length_i ); +} + +INLINE void +String_handle::operator = (char const *p) +{ + copy(); + data->set( p ); +} + +INLINE void +String_handle::trunc(int j) +{ + copy(); data->trunc(j); +} + +INLINE int +String_handle::length_i() const +{ + return data->length_i_; +} + +INLINE bool +String_handle::is_binary_bo() const { + return data->is_binary_bo(); +} + +#endif diff --git a/flower/lib/include/string.hh b/flower/lib/include/string.hh new file mode 100644 index 0000000000..8cef141169 --- /dev/null +++ b/flower/lib/include/string.hh @@ -0,0 +1,193 @@ +/* + + FILE : string.hh -- declare String + + Rehacked by HWN 3/nov/95 + removed String & 's + introduced Class String_handle + */ + +#ifndef STRING_HH +#define STRING_HH + + +#include +#include +#include + +#include "string-handle.hh" + +/** + + Intuitive string class. provides +\begin{itemize} +\item + ref counting through #String_handle# +\item + conversion from bool, int, double, char* , char. +\item + to be moved to String_convert: + conversion to int, upcase, downcase + +\item + printable. + +\item + indexing (index_i, index_any_i, last_index_i) + +\item + cutting (left_str, right_str, mid_str) + +\item + concat (+=, +) + +\item + signed comparison (<, >, ==, etc) + +\item + No operator[] is provided, since this would be enormously slow. If needed, + convert to char const* . +\end{itemize} + +*/ +class String +{ +protected: + String_handle strh_; + + bool null_terminated(); + +public: + + /** init to empty string. This is needed because other + constructors are provided.*/ + String() { } + String(Rational); + + /// String s = "abc"; + String( char const* source ); + String( Byte const* byte_c_l, int length_i ); + + /// "ccccc" + String( char c, int n = 1 ); + + String( int i , char const *fmt=0); + String ( double f , char const* fmt =0); + /// 'true' or 'false' + String(bool ); + + /// return a "new"-ed copy of contents + Byte* copy_byte_p() const; // return a "new"-ed copy of contents + + char const* ch_c_l() const; + Byte const* byte_c_l() const; + char* ch_l(); + Byte* byte_l(); + + /// deprecated; use ch_c_l() + operator char const* () const { return ch_c_l(); } + + String &operator =( const String & source ); + + /// concatenate s + void operator += (char const* s) { strh_ += s; } + void operator += (String s); + + void append(String); + void prepend(String); + + char operator []( int n ) const { return strh_[n]; } + + /// return n leftmost chars + String left_str( int n ) const; + + /// return n rightmost chars + String right_str( int n ) const; + + /// return uppercase of *this + String upper_str() const; + + /// return lowercase of *this + String lower_str() const; + + /// return the "esrever" of *this + String reversed_str() const; + + + /// return a piece starting at index_i (first char = index_i 0), length n + String mid_str(int index_i, int n ) const; + + /// cut out a middle piece, return remainder + String nomid_str(int index_i, int n ) const; + + /// signed comparison, analogous to memcmp; + static int compare_i(const String& s1,const String& s2); + + /// index of rightmost c + int index_last_i( char c) const; + + /// index of rightmost element of string + int index_last_i( char const* string ) const; + + int index_i(char c ) const; + int index_i(String ) const; + int index_any_i(String ) const; + + void to_upper(); + void to_lower(); + /// provide Stream output + void print_on(ostream& os) const; + + /// the length of the string + int length_i() const; + + // ***** depreciated + int len() const { + return length_i(); + } + + /// convert to an integer + int value_i() const; + + /// convert to a double + double value_f() const; +}; + +#include "compare.hh" + +instantiate_compare(const String &, String::compare_i); + +// because char const* also has an operator ==, this is for safety: +inline bool operator==(String s1, char const* s2){ + return s1 == String(s2); +} +inline bool operator==(char const* s1, String s2) +{ + return String(s1)==s2; +} +inline bool operator!=(String s1, char const* s2 ) { + return s1!=String(s2); +} +inline bool operator!=(char const* s1,String s2) { + return String(s2) !=s1; +} + + +inline String +operator + (String s1, String s2) +{ + s1 += s2; + return s1; +} + +inline ostream & +operator << ( ostream& os, String d ) +{ + d.print_on(os); + return os; +} + + +// String quoteString(String message, String quote); + +#endif diff --git a/flower/lib/include/text-db.hh b/flower/lib/include/text-db.hh new file mode 100644 index 0000000000..3535a84f8f --- /dev/null +++ b/flower/lib/include/text-db.hh @@ -0,0 +1,55 @@ +#ifndef TEXTDB_HH +#define TEXTDB_HH + +#include "data-file.hh" + +/**a "const" Array. Contents can't be changed. do "#" comments, read quote enclosed fields */ + +class Text_record : Array +{ + int line_no; + String filename; + +public: + Text_record() { } // needed because of other ctor + + /// report an error in this line. + message(String s) { + cerr << '\n'<< filename << ": "<< line_no << s << "\n"; + } + String operator[](int j) { + return Array::operator[](j); + } + + Text_record(Array s, String fn, int j) : Array(s) { + filename = fn; line_no = j; + } + Array::size; +}; + +/** abstraction for a datafile. + add a subrec/fieldsep/record separator + */ + +class Text_db : private Data_file +{ + void gobble_leading_white(); +public: + /// get a line with records + Text_record get_record(); + + Text_db(String fn):Data_file(fn) { } + Data_file::error; + bool eof(); + + /// get next line. + Text_record operator++(int) { + return get_record(); + } + /// are we done yet? + operator bool() { + return !eof(); + } +}; + +#endif diff --git a/flower/lib/include/text-stream.hh b/flower/lib/include/text-stream.hh new file mode 100644 index 0000000000..437f8698c7 --- /dev/null +++ b/flower/lib/include/text-stream.hh @@ -0,0 +1,74 @@ + +#ifndef TEXTSTR_HH +#define TEXTSTR_HH + +#include +#include +#include "string.hh" +#include "varray.hh" + +/** + line counting input stream. + a stream for textfiles. linecounting. Thin interface getchar and + ungetchar. (ungetc is unlimited) + + should protect get and unget against improper use +*/ + + +class Text_stream +{ + int line_no; + + // could just have used streams. + FILE *f; + Array pushback; + String name; + + public: + Text_stream(String fn); + String get_name() { return name; } + bool eof() { + return feof(f); + } + bool eol() { + return (peek() == '\n'); + } + char peek() { + char c = get(); + unget(c); + return c; + } + int line(){ + return line_no; + } + + char get() { + char c; + + if (pushback.empty()) + c = getc(f); + else + c = pushback.pop(); + + if (c =='\n') + line_no++; + return c; + } + void unget(char c) { + if (c =='\n') + line_no--; + pushback.push(c); + } + ~Text_stream (){ + if (!eof()) + cerr <<__FUNCTION__<< ": closing unended file"; + + fclose(f); + } + + /// GNU format message. + void message(String s); +}; + +#endif diff --git a/flower/lib/include/unionfind.hh b/flower/lib/include/unionfind.hh new file mode 100644 index 0000000000..fbaa51e731 --- /dev/null +++ b/flower/lib/include/unionfind.hh @@ -0,0 +1,25 @@ +#ifndef UNIONFIND_HH +#define UNIONFIND_HH +#include "varray.hh" + +/* + which points of a graph are connected?. + Union find, a standard algorithm: + + Union_find represents an undirected graph of N points. You can + connect two points using #connect()#. #find(i)# finds a uniquely + determined representant of the equivalence class of points + connected to #i#. + + */ +struct Union_find { + void connect(int i, int j); + int find(int i); + bool equiv(int i, int j) { return find(i) == find(j); } + Union_find(int sz); + +private: + Array classes; + +}; +#endif diff --git a/flower/lib/include/varray.hh b/flower/lib/include/varray.hh new file mode 100644 index 0000000000..febf3e7601 --- /dev/null +++ b/flower/lib/include/varray.hh @@ -0,0 +1,186 @@ +/* + (c) Han-Wen Nienhuys 1995,96 + + Distributed under GNU GPL +*/ + +#ifndef ARRAY_H +#define ARRAY_H +#include + +/// copy a bare (C-)array from #src# to #dest# sized #count# +template +inline void arrcpy(T*dest, T*src, int count) { + for (int i=0; i < count ; i++) + *dest++ = *src++; +} + + +/** + Scaleable array/stack template, for a type T with default constructor. + + + This template implements a scaleable vector. With (or without) range + checking. It may be flaky for objects with complicated con- and + destructors. The type T should have a default constructor. It is + best suited for simple types, such as int, double or String, it + provides a paranoidly safe replacement for the new T[int] construct. + + It uses stack terminology, (push, pop, top), and can be used as a stack. + + + */ +template +class Array { +protected: + /// maximum length of array. + int max; + + /// the data itself + T *thearray; + + /// stretch or shrink array. + void remax(int newmax) { + T* newarr = new T[newmax]; + size_ = (newmax < size_) ? newmax : size_; + arrcpy(newarr, thearray, size_); + + delete[] thearray; + thearray = newarr; + max = newmax; + } + int size_; + +public: + /// check invariants + void OK() const { + assert(max >= size_ && size_ >=0); + if (max) assert(thearray); + } + /** report the size_. + @see {setsize_} + */ + int size() const { return size_; } + + /// POST: size() == 0 + void clear() { size_ = 0; } + + Array() { thearray = 0; max =0; size_ =0; } + + + /** set the size_ to #s#. + POST: size() == s. + Warning: contents are unspecified */ + void set_size(int s) { + if (s >= max) remax(s); + size_ = s; + } + + ~Array() { delete[] thearray; } + + /// return a "new"ed copy of array + T* copy_array() const { + T* Tarray = new T[size_]; + arrcpy(Tarray, thearray, size_); + return Tarray; + } + // depracated + operator T* () const { + return copy_array(); + } + void operator=(Array const & src) { + set_size (src.size_); + arrcpy(thearray,src.thearray, size_); + } + Array(const Array & src) { + thearray = src.copy_array(); + max = size_ = src.size_; + } + + /// tighten array size_. + void precompute () { remax(size_); } + + /// this makes Array behave like an array + T &operator[] (const int i) const { + assert(i >=0&&i=0 && j<= size_); + set_size(size_+1); + for (int i=size_-1; i > j; i--) + thearray[i] = thearray[i-1]; + thearray[j] = k; + } + void del(int i) { + assert(i >=0&& i < size_); + arrcpy(thearray+i, thearray+i+1, size_-i-1); + size_--; + } + // quicksort. + void sort (int (*compare)( T const&,T const&), + int lower = -1, int upper = -1 ) { + if (lower < 0) { + lower = 0 ; + upper = size()-1; + } + if (lower >= upper) + return; + swap(lower, (lower+upper)/2); + int last = lower; + for (int i= lower +1; i <= upper; i++) + if (compare(thearray[i], thearray[lower]) < 0 ) + swap( ++last,i); + swap(lower, last); + sort(compare, lower, last-1); + sort(compare, last+1, upper); + } + void concat(Array const &src) { + int s = size_; + set_size(size_ + src.size_); + arrcpy(thearray+s,src.thearray, src.size_); + } + Array subvec(int lower, int upper) { + assert(lower >= 0 && lower <=upper&& upper <= size_); + Array r; + int s =upper-lower; + r.set_size(s); + arrcpy(r.thearray, thearray + lower, s); + return r; + } +}; + +#endif diff --git a/flower/lib/include/vector.hh b/flower/lib/include/vector.hh new file mode 100644 index 0000000000..4d91397cc6 --- /dev/null +++ b/flower/lib/include/vector.hh @@ -0,0 +1,111 @@ +#ifndef VECTOR_HH +#define VECTOR_HH + +#include +#include "real.hh" +#include "varray.hh" + +class Dstream; +class String; +void set_matrix_debug(Dstream&ds); + +/** a row of numbers. + a vector. Storage is handled in Array, Vector only does the mathematics. + */ +class Vector { + Array dat; +public: + void OK() const { dat.OK();} + int dim() const { return dat.size(); } + Vector() { } + Vector(Array d ); + Vector(const Vector&n); + Vector(int n) { + dat.set_size(n); + fill(0); + } + void insert(Real v, int i) { + dat.insert(v,i); + } + void del(int i) { dat.del(i); } + operator String() const; + void fill(Real r) { + for (int i=0; i < dim(); i++) + dat[i] =r; + } + + void operator +=(Vector v) { + assert(v.dim() == dim()); + for (int i=0; i < dim(); i++) + dat[i] += v.dat[i]; + } + + void operator /=(Real a) { + (*this) *= 1/a; + } + + void operator *=(Real a) { + for (int i=0; i < dim(); i++) + dat[i] *= a; + } + + void operator -=(Vector v) { + assert(v.dim() == dim()); + for (int i=0; i < dim(); i++) + dat[i] -= v(i); + } + + Real &operator()(int i) { return dat[i]; } + Real operator()(int i) const { return dat[i]; } + Real elem(int i) { return dat[i]; } + Real operator *(Vector v) const { + Real ip=0; + assert(v.dim() == dim()); + for (int i=0; i < dim(); i++) + ip += dat[i] *v(i); + return ip; + } + Vector operator-() const; + Real norm() { + return sqrt(norm_sq() ); + } + Real norm_sq() { + return ((*this) * (*this)); + } + operator Array () { return dat; } + void print() const; + /// set to j-th element of unit-base + void set_unit(int j) ; +}; + +inline Vector +operator+(Vector a, Vector const &b) { + a += b; + return a; +} + +inline Vector +operator-(Vector a, Vector const &b) { + a -= b; + return a; +} + +inline Vector +operator*(Vector v, Real a) { + v *= a; + return v; +} + +inline Vector +operator*( Real a,Vector v) { + v *= a; + return v; +} + +inline Vector +operator/(Vector v,Real a) { + v *= 1/a; + return v; +} + +#endif diff --git a/flower/lib/include/vsmat.hh b/flower/lib/include/vsmat.hh new file mode 100644 index 0000000000..283b1e567b --- /dev/null +++ b/flower/lib/include/vsmat.hh @@ -0,0 +1,141 @@ +#ifndef VSMAT_HH +#define VSMAT_HH +#include "varray.hh" +#include "real.hh" +/** base class for interface with matrix storageclasses. There are no + iterators for matrixclasses, since matrices are (like arrays) + explicitly int-indexed. + + Iteration is provided by *_next, *_ok, which update and check both + index variables simultaneously. + + TODO + determine type of product matrix. + +*/ +class virtual_smat { + + +public: + /// check invariants + virtual void OK() const=0; + + /// height of matrix + virtual int rows() const = 0; + + /// width of matrix + virtual int cols() const = 0; + + + /** set the size. contents lost. + PRE + i >=0, j>=0 + */ + virtual void set_size(int i, int j) = 0; + + /**set the size to square dimen. contents lost + PRE + i>=0 + */ + virtual void set_size(int i) = 0; + /**set the size to i. + + keep contents. If enlarged contents unspecified + + PRE + i>=0, j>=0 + + */ + virtual void resize(int i, int j) = 0; + + /** + set the size to square dimen. contents kept + Keep contents. If enlarged contents are unspecified + + PRE + i>=0 + */ + virtual void resize(int i) = 0; + + + /** + access an element. + + Generate an errormessage, if this happens + in the 0-part of a sparse matrix. + */ + + virtual Real& elem(int i,int j) = 0; + + /// access a element, no modify + virtual const Real& elem(int i, int j) const = 0; + +#if 1 + virtual Array row(int i) const = 0; + virtual Array column(int j) const = 0; +#endif + + + /** + add a row to the matrix before row k. Contents + of added row are unspecified + + 0 <= k <= rows() + */ + virtual void insert_row(int k)=0; + + + /** + delete a row from this matrix. + + PRE + 0 <= k < rows(); + */ + virtual void delete_row(int k)=0; + virtual void delete_column(int k)=0; + virtual ~virtual_smat() { } + virtual virtual_smat *clone()=0; + + + + /** + at end of matrix?. when doing loop + + for(i=0; i + */ +#include +#include +#include +#include "lgetopt.hh" + +long +Getopt_long::intarg() +{ + long l; + if (sscanf(optarg, "%ld", &l) != 1) + report(E_ILLEGALARG); + + return l; +} + +Long_option_init * +Getopt_long::parselong() +{ + const char *optnm = argv[optind] + 2 ; + assert(*optnm); + + char *endopt = strchr(optnm, '='); + int searchlen = (endopt) ? endopt - optnm : strlen(optnm); + + beet=0; + for (int i=0; i< table_len; i++) { + const char *ln = the_opts[i].longname; + + if (ln && !strncmp(ln, optnm, searchlen)) { + beet = the_opts+i; + break; + } + } + + if (!beet) { + report(E_UNKNOWNOPTION); + return 0; + } + optind++; + optindind = 0; + + + if (beet->take_arg) { + if (endopt) + optarg = endopt +1; // a '=' + else { + optarg = argv[optind]; + optind++; + } + if (!optarg) + report(E_ARGEXPECT); + + } else { + optarg = 0; + if (endopt) + report(E_NOARGEXPECT); + } + + return beet; +} + + +ostream & +Long_option_init::printon(ostream &errorout) +{ + if (shortname) + errorout <<"-" << shortname; + if (shortname && longname) + errorout << ", "; + if (longname) + errorout << "`--" << longname << "'"; + return errorout; +} + +// report an error, GNU style. +void +Getopt_long::report(Errorcod c) +{ + error = c; + if (!errorout) + return; + + *errorout << argv[0] << ": "; + switch (c) { + case E_ARGEXPECT: + *errorout<< "option "; + beet->printon(*errorout); + *errorout << "requires an argument"<longname << "' does not allow an argument"<printon(*errorout); + *errorout << '\n'; + default: + assert(false); + } + exit(2); +} + +Long_option_init * +Getopt_long::parseshort() +{ + char c=argv[optind][optindind]; + beet=0; + assert(c); + + for (int i=0; i < table_len; i++) + if (the_opts[i].shortname == c) { + beet = the_opts+i; + break; + } + + if (!beet){ + report(E_UNKNOWNOPTION); + return 0; + } + + optindind++; + if (!beet->take_arg){ + optarg = 0; + return beet; + } + optarg = argv[optind] + optindind; + + optind ++; + optindind = 0; + + if (!optarg[0]) { + optarg = argv[optind]; + optind ++; + } + if (!optarg) { + report(E_ARGEXPECT); + } + + return beet; +} + +Long_option_init * +Getopt_long::operator()() { + if (!next()) + return 0; + + if (optindind) + return parseshort(); + + if (argv[optind][0] != '-') + return 0; + + if (argv[optind][1] == '-') {// what to do with "command -- bla" + return parselong(); + } else { + optindind = 1; + return parseshort(); + } +} + +Getopt_long::Getopt_long(int c, char **v, Long_option_init *lo) +{ + the_opts = lo; + errorout = &cerr; + argv = v; + argc = c; + optind = 1; + optindind = 0; + + // reached end of option table? + int i; + for (i = 0; the_opts[i].longname ||the_opts[i].shortname; i++) + ; + table_len = i; +} + +bool +Getopt_long::next() +{ + + error = E_NOERROR; + while (optind < argc && !argv[optind][optindind]) { + optind++; + optindind = 0; + } + return (optind < argc); +} + +char * +Getopt_long::current_arg() +{ + if (optind >= argc) + return 0; + char * a = argv[optind]; + return a + optindind; +} + +char * +Getopt_long::get_next_arg() +{ + char * a = current_arg(); + if ( a) { + optind ++; + optindind = 0; + } + return a; +} diff --git a/flower/lib/libc-extension.cc b/flower/lib/libc-extension.cc new file mode 100644 index 0000000000..f9a255683e --- /dev/null +++ b/flower/lib/libc-extension.cc @@ -0,0 +1,113 @@ +/* + libc-extension.cc -- implement some string.h extensions + + source file of the flowerlib + + (c) 1997 Han-Wen Nienhuys +*/ +#include +#include +#include +#include "libc-extension.hh" + +/* + compensate for lacking libc functions. + */ +char* +strnlwr( char* start_l ,int n) +{ + char * p = start_l + n; + while ( --p >= start_l) { + *p = tolower( *p ); /* a macro on some compilers */ + } + return start_l; +} + +char* +strnupr( char* start_l, int n) +{ + char * p = start_l + n; + while ( --p >= start_l) { + *p = toupper( *p ); /* a macro on some compilers */ + } + return start_l; +} + +#ifndef HAVE_MEMMEM + +/** locate a substring. #memmem# finds the first occurrence of + #needle# in #haystack# + */ + +char * +memmem(const Byte * haystack, int haystack_len, + const Byte *needle,int needle_len) +{ + const Byte * end_haystack = haystack + haystack_len - needle_len; + const Byte * end_needle = needle + needle_len ; + + /* Ahhh ... Some minimal lowlevel stuff. This *is* nice; Varation + is the spice of life */ + while (haystack < end_haystack) { + const Byte *subneedle_l = needle; + const Byte *subhaystack_l = haystack; + while (subneedle_l < end_needle) { + if (*subneedle_l++ != *subhaystack_l++) + goto next; // yeah. I should be prosecuted. + } + + // completed the needle. Gotcha. + return (char*) haystack; + next: + haystack++; + } + return 0; +} +#endif + +Byte * +memrchr(const Byte * p, int n, char c) +{ + const Byte * q = p+n; + while (q > p) { + if (*--q == c) + return (Byte*)q; + } + return 0; +} + + +template +inline void +my_swap(T &t1, T &t2, T &tmp) +{ + tmp = t1; + t1 = t2; + t2 = tmp; +} + +Byte* +strrev( Byte* byte_l, int length_i ) +{ + Byte tmp_byte; + + Byte* left_l = byte_l; + Byte* right_l = byte_l + length_i; + + while ( right_l > left_l ) { + my_swap(*right_l-- , *left_l++ , tmp_byte); + } + return byte_l; +} + +#ifndef HAVE_SNPRINTF +int snprintf ( char *str, size_t n, + const char *format, ... ) +{ + va_list ap; + va_start(ap, format); + int i = vsprintf(str, format, ap); + va_end(ap); + return i; +} +#endif diff --git a/flower/lib/matdebug.cc b/flower/lib/matdebug.cc new file mode 100644 index 0000000000..bcc2843bca --- /dev/null +++ b/flower/lib/matdebug.cc @@ -0,0 +1,63 @@ +#include "dstream.hh" +#include "matrix.hh" + +static Dstream *dout = 0; + +/** + Set the debugging output. Will not delete/swallow argument. + */ +void set_matrix_debug(Dstream&ds) +{ + dout = &ds; +} + +Matrix::operator String() const +{ + String s; +#ifndef NPRINT + s="matrix {\n"; + for (int i=0; i< rows(); i++){ + for (int j = 0; j < cols(); j++) { + s+= String(dat->elem(i,j), "%6f "); + } + s+="\n"; + } + s+="}\n"; +#endif + return s; +} + + +void +Matrix::print() const +{ +#ifndef NPRINT + if (!dout) + return; + *dout << *this; +#endif +} + +Vector::operator String() const +{ + String s; +#ifndef NPRINT + s="vector ["; + for (int i=0; i < dim(); i++) { + s += String(dat[i], "%6f") + String(' '); + } + s+="]"; +#endif + return s; +} + + +void +Vector::print() const +{ +#ifndef NDEBUG + if (!dout) + return; + *dout << *this<<'\n'; +#endif +} diff --git a/flower/lib/matrix.cc b/flower/lib/matrix.cc new file mode 100644 index 0000000000..63bd85a33c --- /dev/null +++ b/flower/lib/matrix.cc @@ -0,0 +1,240 @@ +#include "matrix.hh" + +Real +Matrix::norm() const +{ + Real r =0.0; + for (int i=0, j=0; dat->mult_ok(i,j); dat->mult_next(i,j)) + r += sqr(dat->elem(i,j)); + return sqrt(r); +} + +void +Matrix::fill(Real r) +{ + for (int i=0, j=0; dat->mult_ok(i,j); dat->mult_next(i,j)) + dat->elem(i,j)=r; +} + +void +Matrix::set_diag(Real r) +{ + for (int i=0, j=0; dat->mult_ok(i,j); dat->mult_next(i,j)) + dat->elem(i,j)=(i==j) ? r: 0.0; +} + +void +Matrix::set_diag(Vector d) +{ + for (int i=0, j=0; dat->mult_ok(i,j); dat->mult_next(i,j)) + dat->elem(i,j)=(i==j) ? d(i): 0.0; +} + +void +Matrix::operator+=(const Matrix&m) +{ + assert(m.cols() == cols()); + assert(m.rows() == rows()); + for (int i=0, j=0; dat->mult_ok(i,j); dat->mult_next(i,j)) + dat->elem(i,j) += m(i,j); +} + +void +Matrix::operator-=(const Matrix&m) +{ + assert(m.cols() == cols()); + assert(m.rows() == rows()); + for (int i=0, j=0; dat->mult_ok(i,j); dat->mult_next(i,j)) + dat->elem(i,j) -= m(i,j); +} + + +void +Matrix::operator*=(Real a) +{ + for (int i=0, j=0; dat->mult_ok(i,j); dat->mult_next(i,j)) + dat->elem(i,j) *= a; +} + +void +Matrix::operator=(const Matrix&m) +{ + if (&m == this) + return ; + delete dat; + dat = m.dat->clone(); +} + +Matrix::Matrix(const Matrix &m) +{ + m.OK(); + + dat = m.dat->clone(); +} + + +Matrix::Matrix(int n, int m) +{ + dat = virtual_smat::get_full(n,m); + fill(0); +} + +Matrix::Matrix(int n) +{ + dat = virtual_smat::get_full(n,n); + fill(0); +} + +Matrix::Matrix(Vector v, Vector w) +{ + dat = virtual_smat::get_full(v.dim(), w.dim()); + for (int i=0, j=0; dat->mult_ok(i,j); dat->mult_next(i,j)) + dat->elem(i,j)=v(i)*w(j); +} + + +Vector +Matrix::row(int k) const +{ + int n=cols(); + + + Vector v(n); + for(int i=0; i < n; i++) + v(i)=dat->elem(k,i); + + return v; +} + +Vector +Matrix::col(int k) const +{ + int n=rows(); + Vector v(n); + for(int i=0; i < n; i++) + v(i)=dat->elem(i,k); + return v; +} + +Vector +Matrix::left_multiply(const Vector& v) const +{ + Vector dest(v.dim()); + assert(dat->cols()==v.dim()); + for (int i=0, j=0; dat->mult_ok(i,j); dat->mult_next(i,j)) + dest(i)+= dat->elem(j,i)*v(j); + return dest; +} + +Vector +Matrix::operator *(const Vector& v) const +{ + Vector dest(rows()); + assert(dat->cols()==v.dim()); + for (int i=0, j=0; dat->mult_ok(i,j); dat->mult_next(i,j)) + dest(i)+= dat->elem(i,j)*v(j); + return dest; +} + +Matrix +operator /(Matrix const& m1,Real a) +{ + Matrix m(m1); + m /= a; + return m; +} + +void +Matrix::transpose() // delegate to storage? +{ + for (int i=0, j=0; dat->mult_ok(i,j); dat->mult_next(i,j)) { + if (i >= j) + continue; + Real r=dat->elem(i,j); + dat->elem(i,j) = dat->elem(j,i); + dat->elem(j,i)=r; + } +} + +Matrix +Matrix::operator-() const +{ + OK(); + Matrix m(*this); + m*=-1.0; + return m; +} + +Matrix +Matrix::transposed() const +{ + Matrix m(*this); + m.transpose(); + return m; +} + + +/* should do something smarter: bandmatrix * bandmatrix is also banded matrix. */ +Matrix +operator *(const Matrix &m1, const Matrix &m2) +{ + Matrix result(m1.rows(), m2.cols()); + result.set_product(m1,m2); + return result; +} + +void +Matrix::set_product(const Matrix &m1, const Matrix &m2) +{ + assert(m1.cols()==m2.rows()); + assert(cols()==m2.cols() && rows()==m1.rows()); + + for (int i=0, j=0; dat->mult_ok(i,j); + dat->mult_next(i,j)) { + Real r=0.0; + for (int k = 0; k < m1.cols(); k++) + r += m1(i,k)*m2(k,j); + dat->elem(i,j)=r; + } +} + +void +Matrix::insert_row(Vector v, int k) +{ + assert(v.dim()==cols()); + dat->insert_row(k); + for (int j=0; j < cols(); j++) + dat->elem(k,j)=v(j); +} + + +void +Matrix::swap_columns(int c1, int c2) +{ + assert(c1>=0&& c1 < cols()&&c2 < cols() && c2 >=0); + for (int i=0; i< rows(); i++) { + Real r=dat->elem(i,c1); + dat->elem(i,c1) = dat->elem(i,c2); + dat->elem(i,c2)=r; + } +} + +void +Matrix::swap_rows(int c1, int c2) +{ + assert(c1>=0&& c1 < rows()&&c2 < rows() && c2 >=0); + for (int i=0; i< cols(); i++) { + Real r=dat->elem(c1,i); + dat->elem(c1,i) = dat->elem(c2,i); + dat->elem(c2,i)=r; + } +} + + +int +Matrix::dim() const +{ + assert(cols() == rows()); + return rows(); +} + diff --git a/flower/lib/path.cc b/flower/lib/path.cc new file mode 100644 index 0000000000..c79962f00f --- /dev/null +++ b/flower/lib/path.cc @@ -0,0 +1,77 @@ +/* + path.cc - manipulation of paths and filenames. +*/ +#include +#include "path.hh" + +#ifndef PATHSEP +#define PATHSEP '/' +#endif + +/** + @param path the original full filename + @return 4 components of the path. They can be empty +*/ +void +split_path(String path, + String &drive, String &dirs, String &filebase, String &extension) +{ + // peel off components, one by one. + int di = path.index_i(':'); + if (di >= 0) + { + drive = path.left_str(di + 1); + path = path.right_str(path.len() - di -1); + } + else + drive = ""; + + di = path.index_last_i(PATHSEP); + if (di >=0) + { + dirs = path.left_str(di + 1); + path = path.right_str(path.len()-di -1); + } + else + dirs = ""; + + di = path.index_last_i('.'); + if (di >= 0) + { + filebase = path.left_str(di); + extension =path.right_str(path.len()-di); + } + else + { + extension = ""; + filebase = path; + } +} + +File_path::File_path(String pref) +{ + add("."); + add(pref); +} + + +/** find a file. + It will search in the current dir, in the construction-arg, and + in any other added path, in this order. + */ +String +File_path::find(String nm) +{ + for (int i=0; i < size(); i++) { + String path = (*this)[i]; + path+= "/"+nm; + + + FILE *f = fopen(path, "r"); // ugh! + if (f) { + fclose(f); + return path; + } + } + return ""; +} diff --git a/flower/lib/scalar.cc b/flower/lib/scalar.cc new file mode 100644 index 0000000000..5edd9e997f --- /dev/null +++ b/flower/lib/scalar.cc @@ -0,0 +1,57 @@ +#include +#include +#include "scalar.hh" + +Scalar::Scalar(Rational r) + :String(r) +{ + +} + +Scalar::operator Rational() +{ + int p = index_i('/'); + if (p == -1) + return int(*this); + + String s2 = right_str(len()-p-1); + String s1 = left_str(p); + + return Rational(s1.value_i(), s2.value_i()); +} + +bool +Scalar::isnum() +{ + int conv = false; + if (len()) { + long l =0; + conv = sscanf(strh_.ch_c_l(), "%ld", &l); + } + return len() && conv; +} + +Scalar::operator Real() +{ + assert (isnum()); + return value_f(); +} + +Scalar::operator int() +{ + assert (isnum()); + return value_i(); +} + + +Scalar::operator bool() const +{ + if (!len()) + return false; + if (*this == "0") + return false; + String u (*this); + if ( u.upper_str() == "FALSE") + return false; + return true; +} diff --git a/flower/lib/smat.cc b/flower/lib/smat.cc new file mode 100644 index 0000000000..dcc61ce44e --- /dev/null +++ b/flower/lib/smat.cc @@ -0,0 +1,181 @@ +#include "smat.hh" + +void +Full_storage::operator=(Full_storage const &fs) +{ + resize(fs.h, fs.w); + OK(); + fs.OK(); + for (int i=0; i= h && maxw >= w); + assert(h >= 0 && w >= 0); + assert(els||!maxh); +#endif +} +void +Full_storage::resize_cols(int newh) +{ + if (newh <= maxh) { + h=newh; + return; + } + + Real ** newa=new Real*[newh]; + int j=0; + for (; j < h; j++) + newa[j] = els[j]; + for (; j < newh; j++) + newa[j] = new Real[maxw]; + delete[] els; + els=newa; + + h = maxh = newh; +} + +void +Full_storage::resize_rows(int neww) +{ + if (neww <= maxw) { + w=neww; + return; + } + for (int i=0; i < maxh ; i++) { + Real* newa = new Real[neww]; + for (int k=0; k < w; k++) + newa[k] = els[i][k]; + + delete[] els[i]; + els[i] = newa; + } + w = maxw = neww; +} + +Full_storage::~Full_storage() { + for (int i=0; i < maxh; i++) + delete [] els[i]; + delete[] els; +} + +void +Full_storage::resize(int rows, int cols) +{ + OK(); + resize_cols(rows); + resize_rows(cols); + +} + + +bool +Full_storage::mult_ok(int i, int j) const +{ + return valid(i,j); +} + +bool +Full_storage::trans_ok(int i, int j) const +{ + return valid(i,j); +} + + +void +Full_storage::trans_next(int &i, int &j) const +{ + assert(trans_ok(i,j)); + i++; + if (i >= h) { + i=0; + j ++; + } +} + +void +Full_storage::mult_next(int &i, int &j) const +{ + assert(mult_ok(i,j)); + j++; + if (j >= w) { + j=0; + i++; + } +} + +void +Full_storage::delete_column(int k) +{ + assert(0 <= k &&k k ; i--) + for (int j=0; j +Full_storage::row(int n) const +{ + Array r; + for (int j = 0; j < w; j++) + r.push(els[n][j]); + return r; +} + +Array +Full_storage::column(int n) const +{ + + Array r; + for (int i = 0; i +#include "libc-extension.hh" +#include "string.hh" +#include "string-convert.hh" + +/** + a safe length for stringconversion buffers + + worst case would be %f printing HUGE (or 1/HUGE), which is approx + 2e318, this number would have approx 318 zero's in its string. + + Should enlarge buff dynamically. + @see + man 3 snprintf + */ +static const int STRING_BUFFER_LEN=1024; + +String +String_convert::bin2hex_str( String bin_str ) +{ + String str; + Byte const* byte_c_l = bin_str.byte_c_l(); + for ( int i = 0; i < bin_str.length_i(); i++ ) { + str += (char)nibble2hex_byte( *byte_c_l >> 4 ); + str += (char)nibble2hex_byte( *byte_c_l++ ); + } + return str; +} + +int +String_convert::bin2_i( String bin_str ) +{ + assert( bin_str.length_i() <= 4 ); + + int result_i = 0; + for ( int i = 0; i < bin_str.length_i(); i++ ) { + result_i <<= 8; + result_i += (Byte)bin_str[ i ]; + } + return result_i; +} + +// breendet imp from String +int +String_convert::dec2_i( String dec_str ) +{ + if ( !dec_str.length_i() ) + return 0; + + long l = 0; + int conv = sscanf( dec_str.ch_c_l(), "%ld", &l ); + assert( conv ); + + return (int)l; +} + +String +String_convert::longlong_str(long long ll, char const* fmt) +{ + char buffer[STRING_BUFFER_LEN]; + snprintf(buffer, STRING_BUFFER_LEN, + (fmt ? fmt : "%Ld"), ll ); // assume radix 10 + return String(buffer); + +} +// breendet imp from String +double +String_convert::dec2_f( String dec_str ) +{ + if ( !dec_str.length_i() ) + return 0; + double d = 0; + int conv = sscanf( dec_str.ch_c_l(), "%lf", &d ); + assert( conv ); + return d; +} + +int +String_convert::hex2bin_i( String hex_str, String& bin_str_r ) +{ + if ( hex_str.length_i() % 2 ) + hex_str = "0" + hex_str; + + bin_str_r = ""; + Byte const* byte_c_l= hex_str.byte_c_l(); + int i = 0; + while ( i < hex_str.length_i() ) { + int high_i = hex2nibble_i( *byte_c_l++ ); + int low_i = hex2nibble_i( *byte_c_l++ ); + if ( high_i < 0 || low_i < 0 ) + return 1; // illegal char + bin_str_r += String( (char)( high_i << 4 | low_i ), 1 ); + i += 2; + } + return 0; +} + +String +String_convert::hex2bin_str( String hex_str ) +{ + String str; +// silly, asserts should alway be "on"! +// assert( !hex2bin_i( hex_str, str ) ); + int error_i = hex2bin_i( hex_str, str ); + assert( !error_i ); + return str; +} + +int +String_convert::hex2nibble_i( Byte byte ) +{ + if ( byte >= '0' && byte <= '9' ) + return byte - '0'; + if ( byte >= 'A' && byte <= 'F' ) + return byte - 'A' + 10; + if ( byte >= 'a' && byte <= 'f') + return byte - 'a' + 10; + return -1; +} + +// stupido. Should use int_str() +String +String_convert::i2dec_str( int i, int length_i, char ch ) +{ + char fill_ch = ch; + if ( fill_ch) + fill_ch = '0'; + + // ugh + String dec_str( i ); + + // ugh + return String( fill_ch, length_i - dec_str.length_i() ) + dec_str; +} + + +// stupido. Should use int_str() +String +String_convert::i2hex_str( int i, int length_i, char ch ) +{ + String str; + if ( !i ) + str = "0"; + while ( i ) { + str = String( ( i % 16 )["0123456789abcdef"] ) + str; + i /= 16; + } + if ( str.length_i() < length_i ) + str = String( ch, length_i - str.length_i() ) + str; + return str; +} + +Byte +String_convert::nibble2hex_byte( Byte byte ) +{ + if ( ( byte & 0x0f ) <= 9 ) + return ( byte & 0x0f ) + '0'; + else + return ( byte & 0x0f ) - 10 + 'a'; +} +/** + Convert an integer to a string + + @param + #fmt# is a printf style format, default assumes "%d" as format. + */ +String +String_convert::int_str(int i, char const* fmt) +{ + char buffer[STRING_BUFFER_LEN]; + snprintf(buffer, STRING_BUFFER_LEN, + (fmt ? fmt : "%d"), i ); // assume radix 10 + return String(buffer); +} + +/** + Convert a double to a string. + + @param #fmt# is a printf style format, default assumes "%lf" as format + */ +String +String_convert::double_str(double f, char const* fmt) +{ + char buf[STRING_BUFFER_LEN]; + + snprintf(buf, STRING_BUFFER_LEN, fmt ? fmt : "%f", f); + return buf; +} + +/** + Make a string from a single character. + + @param + #n# is a repetition count, default value is 1 + */ +String +String_convert::char_str(char c, int n) +{ + n = n >= 0 ? n : 0; + char* ch_p = new char[ n ]; + memset( ch_p, c, n ); + String s((Byte*)ch_p, n); + delete ch_p; + return s; +} + +String +String_convert::rational_str(Rational r) +{ + char * n = Itoa(r.numerator()); // LEAK???? + + String s = n; + if (r.denominator() != 1) { + char * d = Itoa(r.denominator()); + s += String( '/' ) + String(d); + //delete d; + } +/* delete n; + */ + return s; +} + +String +String_convert::pointer_str(const void *l) +{ + long long int ill = (long long int )l; + return String_convert::longlong_str(ill, "0x%0Lx"); +} diff --git a/flower/lib/stringtest.cc b/flower/lib/stringtest.cc new file mode 100644 index 0000000000..0bbde77c99 --- /dev/null +++ b/flower/lib/stringtest.cc @@ -0,0 +1,118 @@ +#ifdef STRING_TEST +/* + stupid test program to verify stringlib + stringtest.cc + */ +#include +#include "string.hh" +#include "varray.hh" +#include "string-convert.hh" + +void +ctors() +{ + cout << "constructors"< a; + a.push("abcd"); + a.push("zxy"); + a.push("abc"); + a.push(""); + a.sort(String::compare_i); + cout << "compares: "< +*/ + +#ifdef STRING_DEBUG +#include +#include +void* +mymemmove( void* dest, void const* src, size_t n ) +{ + return memcpy( dest, src, n ); // wohltempererit: 69006 +} +#define memmove mymemmove +#endif + +#ifdef STRING_UTILS_INLINED +#undef STRING_UTILS_INLINED +#endif + +#ifdef INLINE +#undef INLINE +#endif + +#define INLINE + +#include "string-handle.hh" +#include "string-data.hh" +#include "string-data.inl" +#include "string-handle.inl" diff --git a/flower/lib/text-db.cc b/flower/lib/text-db.cc new file mode 100644 index 0000000000..ebfc992ff2 --- /dev/null +++ b/flower/lib/text-db.cc @@ -0,0 +1,48 @@ +#include "text-db.hh" +bool +Text_db::eof() +{ + Data_file::gobble_leading_white(); + return Data_file::eof(); +} + +void +Text_db::gobble_leading_white() +{ + while (1) { + Data_file::gobble_leading_white(); + if (eof()) + return ; + char c; + if ((c = data_get()) !='\n'){ + data_unget (c); + return ; + } + } +} + + +Text_record +Text_db::get_record() +{ + while (1) { + String s; + Array fields; + assert(!eof()); + + while ((s = get_word()) != "") + { + fields.push(s); + gobble_white(); + } + + + if (get_line() != "") + assert(false); + + assert (fields.size()); + return Text_record(fields, get_name(), line()); + } +} + + diff --git a/flower/lib/text-stream.cc b/flower/lib/text-stream.cc new file mode 100644 index 0000000000..a2d3e4b119 --- /dev/null +++ b/flower/lib/text-stream.cc @@ -0,0 +1,31 @@ +#include "text-stream.hh" + +Text_stream::Text_stream(String fn) +{ + ios::sync_with_stdio(); + if (fn == "") + { + name = ""; + f = stdin; + } + + else + { + name = fn; + f = fopen(fn, "r"); + } + + if (!f) { + cerr <<__FUNCTION__<< ": can't open `" << fn << "'\n"; + exit(1); + } + + line_no = 1; + } + +void +Text_stream::message(String s) +{ + cerr << "\n"< d) + : dat(d) +{ + +} +Vector::Vector(const Vector&n) + : dat(n.dat) +{ +} + +Vector +Vector::operator-() const +{ + Vector v(*this); + v*=-1; + return v; +} + +void +Vector::set_unit(int j) +{ + fill(0.0); + dat[j] = 1.0; +} diff --git a/flower/matdebug.cc b/flower/matdebug.cc index 1a5d867903..bcc2843bca 100644 --- a/flower/matdebug.cc +++ b/flower/matdebug.cc @@ -2,6 +2,7 @@ #include "matrix.hh" static Dstream *dout = 0; + /** Set the debugging output. Will not delete/swallow argument. */ diff --git a/flower/pcursor.hh b/flower/pcursor.hh index 1215270e3b..ea360078d1 100644 --- a/flower/pcursor.hh +++ b/flower/pcursor.hh @@ -25,14 +25,14 @@ public: Cursor::ok; Cursor::del; Cursor::backspace; - T get() { + T get_p() { T p = ptr(); Cursor::del(); return p; } T get_prev() { (*this)--; - return get(); + return get_p(); } PointerList &list() { return (PointerList&)Cursor::list(); } diff --git a/flower/plist.tcc b/flower/plist.tcc index 1dea8cefc1..2ceed2e9c7 100644 --- a/flower/plist.tcc +++ b/flower/plist.tcc @@ -5,7 +5,7 @@ IPointerList::~IPointerList() { PCursor c( *this ); while (c.ok()) { - delete c.get(); + delete c.get_p(); } } diff --git a/flower/smat.cc b/flower/smat.cc index d89e3bc285..dcc61ce44e 100644 --- a/flower/smat.cc +++ b/flower/smat.cc @@ -19,16 +19,6 @@ Full_storage::OK() const assert(maxh >= h && maxw >= w); assert(h >= 0 && w >= 0); assert(els||!maxh); - if (maxh>0) { // access outer elts. - Real *r = els[maxh -1]; - #if 0 - if (maxw>0) { - assert(r); - Real s = r[maxw -1]; // accessing unitialised memory. - s = sin(s); - } - #endif - } #endif } void @@ -59,7 +49,7 @@ Full_storage::resize_rows(int neww) return; } for (int i=0; i < maxh ; i++) { - Real* newa=new Real[neww]; + Real* newa = new Real[neww]; for (int k=0; k < w; k++) newa[k] = els[i][k]; diff --git a/flower/string-convert.cc b/flower/string-convert.cc index ccd62a0a5a..36c98dd490 100644 --- a/flower/string-convert.cc +++ b/flower/string-convert.cc @@ -7,6 +7,19 @@ #include #include "string.hh" +#include "string-convert.hh" + +/** + a safe length for stringconversion buffers + + worst case would be %f printing HUGE (or 1/HUGE), which is approx + 2e318, this number would have approx 318 zero's in its string. + + Should enlarge buff dynamically. + @see + man 3 snprintf + */ +static const int STRING_BUFFER_LEN=1024; String String_convert::bin2hex_str( String bin_str ) @@ -47,6 +60,15 @@ String_convert::dec2_i( String dec_str ) return (int)l; } +String +String_convert::longlong_str(long long ll, char const* fmt) +{ + char buffer[STRING_BUFFER_LEN]; + snprintf(buffer, STRING_BUFFER_LEN, + (fmt ? fmt : "%Ld"), ll ); // assume radix 10 + return String(buffer); + +} // breendet imp from String double String_convert::dec2_f( String dec_str ) @@ -101,7 +123,8 @@ String_convert::hex2nibble_i( Byte byte ) return byte - 'a' + 10; return -1; } - + +// stupido. Should use int_str() String String_convert::i2dec_str( int i, int length_i, char ch ) { @@ -116,6 +139,8 @@ String_convert::i2dec_str( int i, int length_i, char ch ) return String( fill_ch, length_i - dec_str.length_i() ) + dec_str; } + +// stupido. Should use int_str() String String_convert::i2hex_str( int i, int length_i, char ch ) { @@ -139,3 +164,71 @@ String_convert::nibble2hex_byte( Byte byte ) else return ( byte & 0x0f ) - 10 + 'a'; } +/** + Convert an integer to a string + + @param + #fmt# is a printf style format, default assumes "%d" as format. + */ +String +String_convert::int_str(int i, char const* fmt) +{ + char buffer[STRING_BUFFER_LEN]; + snprintf(buffer, STRING_BUFFER_LEN, + (fmt ? fmt : "%d"), i ); // assume radix 10 + return String(buffer); +} + +/** + Convert a double to a string. + + @param #fmt# is a printf style format, default assumes "%lf" as format + */ +String +String_convert::double_str(double f, char const* fmt) +{ + char buf[STRING_BUFFER_LEN]; + + snprintf(buf, STRING_BUFFER_LEN, fmt ? fmt : "%f", f); + return buf; +} + +/** + Make a string from a single character. + + @param + #n# is a repetition count, default value is 1 + */ +String +String_convert::char_str(char c, int n) +{ + n = n >= 0 ? n : 0; + char* ch_p = new char[ n ]; + memset( ch_p, c, n ); + String s((Byte*)ch_p, n); + delete ch_p; + return s; +} + +String +String_convert::rational_str(Rational r) +{ + char * n = Itoa(r.numerator()); // LEAK???? + + String s = n; + if (r.denominator() != 1) { + char * d = Itoa(r.denominator()); + s += String( '/' ) + String(d); + //delete d; + } +/* delete n; + */ + return s; +} + +String +String_convert::pointer_str(const void *l) +{ + long long int ill = (long long int )l; + return String_convert::longlong_str(ill, "0x%0Lx"); +} diff --git a/flower/string-convert.hh b/flower/string-convert.hh index b96af44bd0..bcf461f8f3 100644 --- a/flower/string-convert.hh +++ b/flower/string-convert.hh @@ -7,28 +7,37 @@ #ifndef STRING_CONVERT_HH #define STRING_CONVERT_HH -/// -#define functor class // :-) +/* + ///a class which only has functions. +//#define functor class // cute. docxx fucks up +*/ + /** The functor String_convert handles all conversions to/from String (some time, anyway). The class is quite empty from data view. */ -functor String_convert { - static int hex2bin_i( String hex_str, String& bin_str_r ); - static int hex2nibble_i( Byte byte ); - static Byte nibble2hex_byte( Byte byte ); +class String_convert { + static int hex2bin_i( String hex_str, String& bin_str_r ); + static int hex2nibble_i( Byte byte ); + static Byte nibble2hex_byte( Byte byte ); public: - static String bin2dec_str( String dec_str ); - static String bin2hex_str( String bin_str ); - static String dec2bin_str( String str ); - static int bin2_i( String str ); - static int dec2_i( String dec_str ); - static double dec2_f( String dec_str ); - static int hex2int_i( String str ); - static String hex2bin_str( String str ); - static String i2hex_str( int i, int length_i, char ch ); - static String i2dec_str( int i, int length_i, char ch ); + static String bin2dec_str( String bin_str ); + static String bin2hex_str( String bin_str ); + static String dec2bin_str( String str ); + static int bin2_i( String str ); + static String char_str(char c, int n); + static int dec2_i( String dec_str ); + static double dec2_f( String dec_str ); + static String double_str(double f, char const* fmt=0); + static int hex2int_i( String str ); + static String hex2bin_str( String str ); + static String int_str(int i, char const *fmt=0 ); + static String i2hex_str( int i, int length_i, char ch ); + static String i2dec_str( int i, int length_i, char ch ); + static String rational_str(Rational); + static String pointer_str(const void *); + static String longlong_str(long long , char const * fmt = 0); }; #endif // __STRING_CONVERT_HH // diff --git a/flower/string.cc b/flower/string.cc index a9368fe4e4..b4687c0b7f 100644 --- a/flower/string.cc +++ b/flower/string.cc @@ -1,87 +1,85 @@ /* - PROJECT: FlowerSoft C++ library - FILE : string.cc - Rehacked by HWN 3/nov/95 - removed String & - introduced class String_handle - */ + string.cc - implement String + + (c) 1997 Han-Wen Nienhuys & Jan Nieuwenhuizen + + */ -#include #include #include -#include + #include +#include #include "string.hh" +#include "libc-extension.hh" +#include "string-convert.hh" #ifdef STRING_DEBUG void* mymemmove( void* dest, void const* src, size_t n ); #define memmove mymemmove #endif -static char* -strlwr( char* s ) -{ - char* p = s; - - while( *p ) { - *p = tolower( *p ); /* a macro on some compilers */ - p++; - } - return s; -} - -static char* -strupr( char* s ) -{ - char* p = s; - - while( *p ) { - *p = toupper( *p ); /* a macro on some compilers */ - p++; - } - return s; -} - -String::String(Rational r) -{ - char * n = Itoa(r.numerator()); // LEAK???? - - *this = n; - if (r.denominator() != 1) { - char * d = Itoa(r.denominator()); - *this += String( '/' ) + String(d); - //delete d; - } -/* delete n; - */ -} - // return array, alloced with new. Byte* String::copy_byte_p() const { Byte const* src = strh_.byte_c_l(); Byte* dest = new Byte[strh_.length_i() + 1]; - memmove( dest, src, strh_.length_i() + 1 ); + memcpy( dest, src, strh_.length_i() + 1 ); return dest; } - void String::print_on(ostream& os) const { - if ( length_i() == strlen( ch_c_l() ) ) + if (strh_.null_terminated_b()) os << ch_c_l(); else for ( int i = 0; i < length_i(); i++ ) os << (Byte)(*this)[ i ]; } + +/* + copying, constructing. + */ +String& +String::operator = (String const&source ) +{ + strh_ = source.strh_; + return *this; +} + + +String::String(Rational r) +{ + *this = String_convert::rational_str(r); +} + +String::String (double f, char const* fmt) +{ + *this= String_convert::double_str(f,fmt); +} + +String::String( char c, int n ) +{ + *this = String_convert::char_str (c,n); +} + +/** + @see + String_convert::int_str + */ +String::String(int i, const char * format ) +{ + *this = String_convert::int_str(i,format); +} String::String (bool b) { *this = (char const* ) (b ? "true" : "false"); } + String::String( char const* source ) { assert(source); @@ -90,50 +88,31 @@ String::String( char const* source ) String::String( Byte const* byte_l, int length_i ) { -// assert( !length_i || byte_l );// ugh. Storing null pointers? strh_.set( byte_l, length_i ); } - + void -String::operator +=(String s) +String::append(String s) { strh_.append( s.byte_c_l(), s.length_i() ); } - -int -String::length_i() const -{ - return strh_.length_i(); -} - -// will go away, fixed anyway -String::String( char c, int n ) +void +String::operator +=(String s) { - n = n >= 0 ? n : 0; - char* ch_p = new char[ n ]; - memset( ch_p, c, n ); - strh_.set( (Byte*)ch_p, n ); - delete ch_p; + append(s); } -String::String(int i) +void +String::prepend(String s) { - char digits[ 81 ]; // who the fuck is 80??? - digits[ 0 ] = '\0'; - sprintf(digits, "%d", i ); // assume radix 10 - strh_ = digits; + s += *this; + *this = s; } -String::String( const int i, const int n, char const c ) +int +String::length_i() const { - char fill_ch = c; - if ( fill_ch) - fill_ch = '0'; - - String v( i ); - - String str = String( fill_ch, n - v.length_i() ) + String( v ); - strh_.set( str.byte_c_l(), str.length_i() ); + return strh_.length_i(); } Byte const* @@ -160,7 +139,9 @@ String::ch_l() return strh_.ch_l(); } -// signed comparison, analogous to memcmp; +/** + Do a signed comparison, analogous to memcmp; + */ int String::compare_i(String const& s1, String const& s2 ) { @@ -177,96 +158,99 @@ String::compare_i(String const& s1, String const& s2 ) return result ? result : i1-i2; } - + int String::index_last_i( char const c ) const { - // not binary safe - assert( length_i() == strlen( ch_c_l() ) ); - if ( !length_i() ) - return -1; - - char const* me = strh_.ch_c_l(); - char const* p = strrchr(me, c ); - if ( p ) - return p - me; + if ( !length_i() ) return -1; + + char const* me = strh_.ch_c_l(); + char const* p = memrchr(me, length_i(), c ); + if ( p ) + return p - me; + return -1; } int -String::index_last_i( char const* string ) const -{ - // not binary safe - assert( length_i() == strlen( ch_c_l() ) ); - - int length = strlen( string ); - if ( !length_i() || !length ) - return -1; - - int next_i = index_i( string ); - if ( next_i == -1 ) - return -1; - - int index_i = 0; - while( next_i >= 0 ) { - index_i += next_i; - next_i = right_str( length_i() - index_i - length ).index_i( string ); - } - return index_i; +String::index_last_i( char const* string ) const // UGK! +{ + assert(false); // broken + int length = strlen( string ); // ugrh + if ( !length_i() || !length ) + return -1; + + int next_i = index_i( string ); + if ( next_i == -1 ) + return -1; + + int index_i = 0; + while( next_i >= 0 ) { + index_i += next_i; + next_i = right_str( length_i() - index_i - length ).index_i( string ); + } + return index_i; } -// find c -// return -1 if not found. +/** find a character. + + @return + the index of the leftmost character #c# (0 <= return < length_i()), + or -1 if not found. -// ? should return length_i()?, as in string.left_str(index_i(delimiter)) + ? should return length_i()?, as in string.left_str(index_i(delimiter)) +*/ int String::index_i(char c ) const { - // not binary safe - assert( length_i() == strlen( ch_c_l() ) ); - if ( !length_i() ) - return -1; - - char const* me = strh_.ch_c_l(); - char const* p = strchr( me, c ); - if ( p ) - return p - me; - return -1; + char const* me = strh_.ch_c_l(); + char const* p = (char const *) memchr( me,c, length_i()); + if ( p ) + return p - me; + return -1; } -// find searchfor. (what if this == "" && searchfor == "") ??? +/** + find the substring. + + @return + index of leftmost occurrence of #searchfor# + */ int -String::index_i( char const* searchfor ) const -{ - // not binary safe - assert( length_i() == strlen( ch_c_l() ) ); - if ( !length_i() || !searchfor ) - return -1; - - char const* me = strh_.ch_c_l(); - char const* p = strstr(me, searchfor); - if ( p ) - return p - me; +String::index_i( String searchfor ) const +{ + char const* me = strh_.ch_c_l(); + char const* p = (char const *) memmem(me, length_i(), searchfor.ch_c_l(), + searchfor.length_i()); + + if ( p ) + return p - me; + else return -1; } -// find chars of a set. +/** find chars of a set. + + @return + the index of the leftmost occurance of an element of #set# + */ int -String::index_any_i( char const* string ) const -{ - // not binary safe - assert( length_i() == strlen( ch_c_l() ) ); - - if ( !length_i() || !string ) - return -1; - - char const* s = (char const* )strh_.ch_c_l(); - char const* p = strpbrk( s, string ); - if ( p ) - return p - s; +String::index_any_i( String set ) const +{ + int n = length_i(); + if ( !n ) return -1; -} + const void * me_l = (const void*) strh_.ch_c_l(); + for (int i=0; i < set.length_i(); i++) { + char * found=(char*) memchr(me_l, set[i], n ); + if (found) { + return found - me_l; + } + } + return -1; +} + String String::left_str( int n ) const { @@ -282,8 +266,6 @@ String::left_str( int n ) const return retval; } - -// n rightmst chars String String::right_str( int n ) const { @@ -291,7 +273,7 @@ String::right_str( int n ) const return *this; if ( n < 1) - String(); + return ""; return String( strh_.byte_c_l() + length_i() - n, n ); } @@ -300,110 +282,80 @@ String::right_str( int n ) const String String::nomid_str( int index_i, int n ) const { - if ( index_i < 0 ) - return String(); - if ( index_i >= length_i() ) - return *this; + if ( index_i < 0 ) { + n += index_i; + index_i = 0; + } + if ( n <= 0) + return *this; - return String( String( left_str( index_i ) ) + right_str( length_i() - index_i - n )); + return + left_str( index_i ) + + right_str( length_i() - index_i - n ) ; } - +/* + proposal: change to "cut()" + */ String String::mid_str( int index_i, int n ) const { - if ( !length_i() || ( index_i < 0 ) || ( index_i >= length_i() ) || ( n < 1 ) ) - return String(); + if ( !length_i() || ( index_i < 0 ) || ( index_i >= length_i() ) || ( n < 1 ) ) + return String(); - if ( ( n > length_i() ) || ( index_i + n > length_i() ) ) - n = length_i() - index_i; + if ( ( n > length_i() ) || ( index_i + n > length_i() ) ) + n = length_i() - index_i; - return String( byte_c_l() + index_i, n ); + return String( byte_c_l() + index_i, n ); } - - -// return uppercase + String String::upper_str() const { - // not binary safe - assert( length_i() == strlen( ch_c_l() ) ); String str = *this; - char *s = str.strh_.byte_l(); - strupr( s ); + str.to_upper(); return str; } +void +String::to_upper() +{ + char *s = (char*)strh_.byte_l(); + strnupr( s ,length_i()); +} + +void +String::to_lower() +{ + char* s = strh_.ch_l(); + strnlwr(s,length_i()); +} -// return lowercase String String::lower_str() const { - // not binary safe - assert( length_i() == strlen( ch_c_l() ) ); String str = *this; - char* s = str.strh_.ch_l(); - strlwr(s); + str.to_lower(); return str; } - -String::String (double f, char const* fmt) +String +String::reversed_str() const { - /* worst case would be printing HUGE (or 1/HUGE), which is approx - 2e318, this number would have approx 318 zero's in its string. - - 1024 is a safe length for the buffer - */ - - char buf[1024]; - if (!fmt) - sprintf(buf, "%f", f); - else - sprintf(buf, fmt,f); - *this = buf; + String str = *this; + strrev( str.byte_l(), str.length_i() ); + return str; } int String::value_i() const { - return String_convert::dec2_i( *this ); + return String_convert::dec2_i( *this ); } double String::value_f() const { - return String_convert::dec2_f( *this ); + return String_convert::dec2_f( *this ); } -#if 0 -String -quoteString( String msg, String quote) -{ - return msg + " `" + quote + "' "; -} -#endif // 0 - -Byte* -strrev( Byte* byte_l, int length_i ) -{ - Byte byte; - Byte* left_byte_l = byte_l; - Byte* right_byte_l = byte_l + length_i; - - while ( right_byte_l > left_byte_l ) { - byte = *left_byte_l; - *left_byte_l++ = *right_byte_l; - *right_byte_l-- = byte; - } - return byte_l; -} - - -String -String::reversed_str() const -{ - String str = *this; - strrev( str.byte_l(), str.length_i() ); - return str; -} diff --git a/flower/string.hh b/flower/string.hh index 7aa19047d1..8cef141169 100644 --- a/flower/string.hh +++ b/flower/string.hh @@ -15,7 +15,7 @@ #include #include -#include "stringhandle.hh" +#include "string-handle.hh" /** @@ -24,15 +24,12 @@ \item ref counting through #String_handle# \item - - conversion from bool, int, double, char* , char. + conversion from bool, int, double, char* , char. \item - to be moved to String_convert: conversion to int, upcase, downcase \item - printable. \item @@ -51,35 +48,34 @@ No operator[] is provided, since this would be enormously slow. If needed, convert to char const* . \end{itemize} + */ class String { protected: - String_handle strh_; // should derive String from String_handle? + String_handle strh_; + bool null_terminated(); + public: - /** init to "". needed because other constructors are provided.*/ + /** init to empty string. This is needed because other + constructors are provided.*/ String() { } String(Rational); + /// String s = "abc"; String( char const* source ); - String( Byte const* byte_c_l, int length_i ); /// "ccccc" String( char c, int n = 1 ); - /// String s( 10 ); - String( int i ); - + String( int i , char const *fmt=0); + String ( double f , char const* fmt =0); /// 'true' or 'false' String(bool ); - /// String s( 3.14, 6, '#' ); - String ( double f , char const* fmt =0); - String( int i, int n, char c = ' ' ); - /// return a "new"-ed copy of contents Byte* copy_byte_p() const; // return a "new"-ed copy of contents @@ -91,12 +87,15 @@ public: /// deprecated; use ch_c_l() operator char const* () const { return ch_c_l(); } - String operator =( const String & source ) { strh_ = source.strh_; return *this; } + String &operator =( const String & source ); /// concatenate s void operator += (char const* s) { strh_ += s; } void operator += (String s); + void append(String); + void prepend(String); + char operator []( int n ) const { return strh_[n]; } /// return n leftmost chars @@ -130,17 +129,12 @@ public: /// index of rightmost element of string int index_last_i( char const* string ) const; - /** - index of leftmost c. - - @return - -1 if not found, else index - */ int index_i(char c ) const; - int index_i(char const* string ) const; - int index_any_i(char const* string ) const; - + int index_i(String ) const; + int index_any_i(String ) const; + void to_upper(); + void to_lower(); /// provide Stream output void print_on(ostream& os) const; @@ -157,7 +151,6 @@ public: /// convert to a double double value_f() const; - // ***** }; #include "compare.hh" @@ -197,6 +190,4 @@ operator << ( ostream& os, String d ) // String quoteString(String message, String quote); -#include "string-convert.hh" - #endif diff --git a/flower/stringdata.hh b/flower/stringdata.hh deleted file mode 100644 index ba9099c440..0000000000 --- a/flower/stringdata.hh +++ /dev/null @@ -1,94 +0,0 @@ -/* - stringdata.hh -- declare String_data - - source file of the LilyPond music typesetter - - (c) 1997 Han-Wen Nienhuys -*/ - - -#ifndef STRINGDATA_HH -#define STRINGDATA_HH - - -/**Internal String struct. - the data itself. Handles simple tasks (resizing, resetting) - */ -class String_data { - // GNU malloc: storage overhead is 8 bytes anyway. - -friend class String_handle; - int maxlen; // maxlen is arraysize-1 - - int length_i_; - Byte* data_byte_p_; - int references; - - /// init to "" - String_data(); - - /// init from src. Conservative allocation. - String_data(String_data const &src); - - ~String_data(); - - /** POST: maxlen >= j. - @param j, maximum stringlength_i_. - contents thrown away. - */ - void setmax(int j); - - /** POST: maxlen >= j. - @param j, maximum stringlength_i_. - contents are kept if it grows. - */ - void remax(int j); - - /// check if writeable. - void OKW(); - - /// check state. - void OK(); - - /// reduce memory usage. - void tighten(); - - // assignment. - void set( Byte const* byte_c_l, int length_i ); - - void set( char const* ch_c_l ); - - /// concatenation. - void append( Byte const* byte_c_l, int length_i ); - - void operator += ( char const* ch_c_l ); - - char const* ch_c_l() const; - - char* ch_l(); - - Byte const* byte_c_l() const; - - // idem, non const - Byte* byte_l(); - - void trunc(int j); - - /** access element. not really safe. Can alter length_i_ without - #String_data# knowing it. */ - Byte &operator [](int j); - Byte operator [](int j) const; -}; - - - -#ifdef STRING_UTILS_INLINED -#ifndef INLINE -#define INLINE inline -#endif -#include "stringdata.inl" - -#endif - - -#endif // STRING_DATA_HH diff --git a/flower/stringdata.inl b/flower/stringdata.inl deleted file mode 100644 index 7b55481085..0000000000 --- a/flower/stringdata.inl +++ /dev/null @@ -1,215 +0,0 @@ -/* -*-C++-*- - String_data.inl -- implement String_data - - source file of Flower lib - - (c) 1997 Han-Wen Nienhuys -*/ - -#ifndef STRINGDATA_INL -#define STRINGDATA_INL - -#include -#include - -#include "stringdata.hh" -const int INITIALMAX=8; - -#include -void* -mymemmove( void* dest, void const* src, size_t n ); -#if 0 // redef STRING_DEBUG -INLINE void* -mymemmove( void* dest, void const* src, size_t n ) -{ - return memmove( dest, src, n ); // wohltempererit: 69006 -} -#define memmove mymemmove -#endif - -INLINE void -String_data::OKW() -{ - assert (references == 1); -} - -INLINE void -String_data::OK() -{ - assert(maxlen >= length_i_); - assert(bool(data_byte_p_)); - assert(references >= 1); -} - - -INLINE -String_data::String_data() -{ - references=0; - maxlen = INITIALMAX; - data_byte_p_ = new Byte[maxlen + 1]; - data_byte_p_[0] = 0; - length_i_ = 0; -} - -INLINE -String_data::String_data(String_data const &src) -{ - references=0; - maxlen = length_i_ = src.length_i_; - data_byte_p_ = new Byte[maxlen+1]; // should calc GNU 8byte overhead. - memmove( data_byte_p_, src.data_byte_p_, length_i_ + 1 ); -} - -INLINE -String_data::~String_data() -{ - assert(references == 0); - delete[] data_byte_p_; -} - -INLINE void -String_data::setmax(int j) -{ - OKW(); - if (j > maxlen) { - delete data_byte_p_; - maxlen = j; - data_byte_p_ = new Byte[maxlen + 1]; - - data_byte_p_[0] = 0; - length_i_ = 0; - } -} - -/* this is all quite hairy: - update of length_i_ - update of maxlen - alloc of buffer - copying of buffer - needs blondification: - split tasks - define change authority -*/ -INLINE void -String_data::remax(int j) -{ - OKW(); - if (j > maxlen) { -// maxlen = j; oeps -// Byte *p = new Byte[maxlen + 1]; - Byte *p = new Byte[j + 1]; - memmove( p, data_byte_p_, ( maxlen = 0 && j <= length_i_); - data_byte_p_[j] = 0; - length_i_ = j; -} - -INLINE Byte& -String_data::operator [](int j) -{ - assert(j >= 0 && j <= length_i_); - return data_byte_p_[j] ; -} - -INLINE Byte -String_data::operator [](int j) const -{ - assert(j >= 0 && j <= length_i_); - return data_byte_p_[j]; -} - - - - -#endif // __STRING_UTIL_CC // diff --git a/flower/stringhandle.hh b/flower/stringhandle.hh deleted file mode 100644 index df92e50216..0000000000 --- a/flower/stringhandle.hh +++ /dev/null @@ -1,70 +0,0 @@ -/* - stringhandle.hh -- declare String_handle - - source file of the LilyPond music typesetter - - (c) 1997 Han-Wen Nienhuys -*/ - - -#ifndef STRINGHANDLE_HH -#define STRINGHANDLE_HH -#include "fproto.hh" - - -/** - Reference counting for strings. - - handles ref. counting, and provides a very thin interface using - Byte * - - */ -class String_handle { - String_data* data; - - /// decrease ref count. Named kind of like a Tanenbaum semafore - void down(); - - /// increase ref count - void up(String_data *d); - - /** make sure data has only one reference. - POST: data->references == 1 - */ - void copy(); - -public: - String_handle(); - ~String_handle(); - String_handle(String_handle const & src); - - Byte const* byte_c_l() const; - char const* ch_c_l() const; - Byte* byte_l(); - char* ch_l(); - - void operator =(String_handle const &src); - void operator += (char const *s); - Byte operator[](int j) const; - - /** Access elements. WARNING: NOT SAFE - don't use this for loops. Use byte_c_l() - */ - Byte &operator[](int j); - void append( Byte const* byte_c_l, int length_i ); - void set( Byte const* byte_c_l, int length_i ); - void operator = (char const *p); - void trunc(int j); - int length_i() const; -}; - -#ifdef STRING_UTILS_INLINED -#ifndef INLINE -#define INLINE inline -#endif -#include "stringhandle.inl" -/* we should be resetting INLINE. oh well. */ -#endif - - -#endif // STRINGHANDLE_HH diff --git a/flower/stringhandle.inl b/flower/stringhandle.inl deleted file mode 100644 index bc84cd868b..0000000000 --- a/flower/stringhandle.inl +++ /dev/null @@ -1,151 +0,0 @@ -/* -*-c++-*- - - stringhandle.inl -- implement String_handle - - source file of Flower lib - - (c) 1997 Han-Wen Nienhuys -*/ - -#ifndef STRINGHANDLE_INL -#define STRINGHANDLE_INL - -#include -#include - -#include "stringdata.hh" -#include "stringhandle.hh" - -INLINE void -String_handle::down() -{ - if (!(--data->references)) delete data; data = 0; -} - -/// increase ref count -INLINE void -String_handle::up(String_data *d) -{ - data=d; data->references ++; -} - -INLINE void -String_handle::copy() -{ - if (data->references !=1){ - String_data *newdata = new String_data(*data); - down(); - up(newdata); - } -} - -INLINE -String_handle::String_handle() -{ - up(new String_data); -} - -INLINE -String_handle::~String_handle() -{ - down(); -} - -INLINE -String_handle::String_handle(String_handle const & src) -{ - up(src.data); -} - -INLINE Byte* -String_handle::byte_l() -{ - copy(); - return data->byte_l(); -} - -INLINE char* -String_handle::ch_l() -{ - copy(); - return (char*)data->byte_l(); -} - -INLINE Byte -const* String_handle::byte_c_l() const -{ - return data->byte_c_l(); -} - -INLINE char const* -String_handle::ch_c_l() const -{ - return (char const*)data->byte_c_l(); -} - -INLINE void -String_handle::operator =(String_handle const &src) -{ - if (this == &src) - return; - down(); - up(src.data); -} - -INLINE void -String_handle::operator += (char const *s) -{ - copy(); - *data += s; -} - - -INLINE Byte -String_handle::operator[](int j) const -{ - return (*data)[j]; -} - -// !NOT SAFE! -// don't use this for loops. Use byte_c_l() -INLINE Byte & -String_handle::operator[](int j) -{ - copy(); // hmm. Not efficient - return data->byte_l()[j]; -} - -INLINE void -String_handle::append( Byte const* byte_c_l, int length_i ) -{ - copy(); - data->append( byte_c_l, length_i ); -} - -INLINE void -String_handle::set( Byte const* byte_c_l, int length_i ) -{ - copy(); - data->set( byte_c_l, length_i ); -} - -INLINE void -String_handle::operator = (char const *p) -{ - copy(); - data->set( p ); -} - -INLINE void -String_handle::trunc(int j) -{ - copy(); data->trunc(j); -} - -INLINE int -String_handle::length_i() const -{ - return data->length_i_; -} - -#endif diff --git a/flower/stringtest.cc b/flower/stringtest.cc index c0c50da5c6..2f085a26d7 100644 --- a/flower/stringtest.cc +++ b/flower/stringtest.cc @@ -1,42 +1,113 @@ -// stringtest.cc - +/* + stupid test program to verify stringlib + stringtest.cc + */ #include #include "string.hh" +#include "varray.hh" +#include "string-convert.hh" + +void +ctors() +{ + cout << "constructors"< a; + a.push("abcd"); + a.push("zxy"); + a.push("abc"); + a.push(""); + a.sort(String::compare_i); + cout << "compares: "< fields; - assert(!eof()); - - while ((s = get_word()) != "") - { - fields.push(s); - gobble_white(); - } - - - if (get_line() != "") - assert(false); - - assert (fields.size()); - return Text_record(fields, get_name(), line()); - } -} - - diff --git a/flower/textdb.hh b/flower/textdb.hh deleted file mode 100644 index c2cff2461b..0000000000 --- a/flower/textdb.hh +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef TEXTDB_HH -#define TEXTDB_HH - -#include "datafile.hh" - -/**a "const" Array. Contents can't be changed. do "#" comments, read quote enclosed fields */ - -class Text_record : Array -{ - int line_no; - String filename; - -public: - Text_record() { } // needed because of other ctor - - /// report an error in this line. - message(String s) { - cerr << '\n'<< filename << ": "<< line_no << s << "\n"; - } - String operator[](int j) { - return Array::operator[](j); - } - - Text_record(Array s, String fn, int j) : Array(s) { - filename = fn; line_no = j; - } - Array::size; -}; - -/** abstraction for a datafile. - add a subrec/fieldsep/record separator - */ - -class Text_db : private Data_file -{ - void gobble_leading_white(); -public: - /// get a line with records - Text_record get_record(); - - Text_db(String fn):Data_file(fn) { } - Data_file::error; - bool eof(); - - /// get next line. - Text_record operator++(int) { - return get_record(); - } - /// are we done yet? - operator bool() { - return !eof(); - } -}; - -#endif diff --git a/flower/textstream.cc b/flower/textstream.cc deleted file mode 100644 index 5ab3f3fcde..0000000000 --- a/flower/textstream.cc +++ /dev/null @@ -1,31 +0,0 @@ -#include "textstream.hh" - -Text_stream::Text_stream(String fn) -{ - ios::sync_with_stdio(); - if (fn == "") - { - name = ""; - f = stdin; - } - - else - { - name = fn; - f = fopen(fn, "r"); - } - - if (!f) { - cerr <<__FUNCTION__<< ": can't open `" << fn << "'\n"; - exit(1); - } - - line_no = 1; - } - -void -Text_stream::message(String s) -{ - cerr << "\n"< -#include -#include "string.hh" -#include "varray.hh" - -/** - line counting input stream. - a stream for textfiles. linecounting. Thin interface getchar and - ungetchar. (ungetc is unlimited) - - should protect get and unget against improper use -*/ - - -class Text_stream -{ - int line_no; - - // could just have used streams. - FILE *f; - Array pushback; - String name; - - public: - Text_stream(String fn); - String get_name() { return name; } - bool eof() { - return feof(f); - } - bool eol() { - return (peek() == '\n'); - } - char peek() { - char c = get(); - unget(c); - return c; - } - int line(){ - return line_no; - } - - char get() { - char c; - - if (pushback.empty()) - c = getc(f); - else - c = pushback.pop(); - - if (c =='\n') - line_no++; - return c; - } - void unget(char c) { - if (c =='\n') - line_no--; - pushback.push(c); - } - ~Text_stream (){ - if (!eof()) - cerr <<__FUNCTION__<< ": closing unended file"; - - fclose(f); - } - - /// GNU format message. - void message(String s); -}; - -#endif diff --git a/flower/varray.hh b/flower/varray.hh index d2c2f55321..febf3e7601 100644 --- a/flower/varray.hh +++ b/flower/varray.hh @@ -17,13 +17,18 @@ inline void arrcpy(T*dest, T*src, int count) { /** - scaleable array/stack template, for T with def ctor. + Scaleable array/stack template, for a type T with default constructor. + + This template implements a scaleable vector. With (or without) range checking. It may be flaky for objects with complicated con- and destructors. The type T should have a default constructor. It is - best suited for simple types, such as int, double or String + best suited for simple types, such as int, double or String, it + provides a paranoidly safe replacement for the new T[int] construct. It uses stack terminology, (push, pop, top), and can be used as a stack. + + */ template class Array { @@ -146,7 +151,7 @@ public: size_--; } // quicksort. - void sort (int (*compare)(T& , T& ), + void sort (int (*compare)( T const&,T const&), int lower = -1, int upper = -1 ) { if (lower < 0) { lower = 0 ; diff --git a/genheader b/genheader deleted file mode 100755 index 7c36afe0ae..0000000000 --- a/genheader +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/perl -w - -die "arg needed\n" if (!($#ARGV+1)); -my $fn = $ARGV[0]; -my $hh_q = ($fn =~ /hh$/ ); -my $MAILADRESS=$ENV{MAILADRESS}; -my @pw=(getpwuid($<)); -my $username=$pw[6]; -my $what="implement "; -$what = "declare " if ($hh_q); -my $headstr ="/* - $fn -- $what - - source file of the LilyPond music typesetter - - (c) 1997 $username <$MAILADRESS> -*/\n"; - -my $startdef= $fn; -$startdef =~ s/[\.-]/_/g; -$startdef =~ tr/a-z/A-Z/; -my $terminatestr="\n"; -if ($hh_q) { - $headstr .= "\n\n#ifndef $startdef\n#define $startdef\n"; - $terminatestr .= "#endif // $startdef\n" -} - -print $headstr, $terminatestr; - - - diff --git a/hdr/Makefile b/hdr/Makefile deleted file mode 100644 index aab2511d4f..0000000000 --- a/hdr/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -default: - $(MAKE) -C .. -DISTFILES=Makefile $(allhdr) -dist: - ln $(DISTFILES) $(DDIR)/$(SUBDIR) - - -TAGS: $(hdr) - $(TAGSACTION) $^ - -clean: - rm -f parser.hh - rm -f midi-parser.hh diff --git a/hdr/bar-reg.hh b/hdr/bar-reg.hh deleted file mode 100644 index c73e5d1f4f..0000000000 --- a/hdr/bar-reg.hh +++ /dev/null @@ -1,31 +0,0 @@ -/* - bar-reg.hh -- declare Bar_register - - source file of the LilyPond music typesetter - - (c) 1997 Han-Wen Nienhuys -*/ - - -#ifndef BARREG_HH -#define BARREG_HH -#include "register.hh" - -/** - generate bars. Either user ("|:"), or default (new measure) - */ -class Bar_register : public Request_register { - void split_bar(Bar *& pre, Bar * no, Bar * &post); -public: - Bar_req * bar_req_l_; - Bar * bar_p_; - - virtual bool try_request(Request *req_l); - virtual void process_requests(); - virtual void pre_move_processing(); - virtual void post_move_processing(); - Bar_register(); - NAME_MEMBERS(Bar_register); -}; - -#endif // BARREG_HH diff --git a/hdr/bar.hh b/hdr/bar.hh deleted file mode 100644 index 3727358d96..0000000000 --- a/hdr/bar.hh +++ /dev/null @@ -1,20 +0,0 @@ -/* - bar.hh -- part of LilyPond - - (c) 1996,97 Han-Wen Nienhuys -*/ - -#ifndef BAR_HH -#define BAR_HH -#include "item.hh" - -struct Bar: Item { - String type; - - Bar(String type); -NAME_MEMBERS(Bar); - void do_print() const; - Molecule*brew_molecule_p()const; -}; -#endif // BAR_HH - diff --git a/hdr/beam.hh b/hdr/beam.hh deleted file mode 100644 index 8eb2f148b5..0000000000 --- a/hdr/beam.hh +++ /dev/null @@ -1,51 +0,0 @@ -/* - beam.hh -- part of LilyPond - - (c) 1996,97 Han-Wen Nienhuys -*/ - -#ifndef BEAM_HH -#define BEAM_HH -#include "proto.hh" -#include "directional-spanner.hh" -#include "plist.hh" - -/** a beam connects multiple stems Beam adjusts the stems its owns to - make sure that they reach the beam and that point in the correct - direction */ -struct Beam: public Directional_spanner { - PointerList stems; - /// the slope of the beam in posns / point (dimension) - Real slope; - - /// position of leftmost end of beam - Real left_pos; - - - /* *************** */ -NAME_MEMBERS(Beam); - - virtual Interval width()const; - Offset center() const; - Spanner *do_break_at(PCol *, PCol *) const; - Beam(); - void add(Stem*); - - - void set_default_dir(); - void do_pre_processing(); - void do_post_processing(); - - void do_print() const; - void set_grouping(Rhythmic_grouping def, Rhythmic_grouping current); - void set_stemlens(); - ~Beam(); - -private: - Molecule stem_beams(Stem *here, Stem *next, Stem *prev)const; - void solve_slope(); - Molecule*brew_molecule_p()const; -}; - -#endif // BEAM_HH - diff --git a/hdr/boxes.hh b/hdr/boxes.hh deleted file mode 100644 index 22a2eec3a5..0000000000 --- a/hdr/boxes.hh +++ /dev/null @@ -1,31 +0,0 @@ -/* - some 2D geometrical concepts -*/ - -#ifndef BOXES_HH -#define BOXES_HH - -#include "fproto.hh" -#include "real.hh" -#include "interval.hh" -#include "offset.hh" - -/// a square subset of Real^2 -struct Box { - Interval x, y; - - void translate(Offset o) { - x.translate(o.x); - y.translate(o.y); - } - /// smallest box enclosing #b# - void unite(Box b) { - x.unite(b.x); - y.unite(b.y); - } - Box(); - Box(Interval ix, Interval iy); -}; - - -#endif diff --git a/hdr/break.hh b/hdr/break.hh deleted file mode 100644 index 886e2d788b..0000000000 --- a/hdr/break.hh +++ /dev/null @@ -1,44 +0,0 @@ -/* - break.hh -- part of LilyPond - - (c) 1996,97 Han-Wen Nienhuys -*/ - -#ifndef BREAK_HH -#define BREAK_HH -#include "varray.hh" -#include "proto.hh" -#include "colhpos.hh" - -/** Class representation of an algorithm which decides where to put - the column, and where to break lines. */ -struct Break_algorithm { - PScore &pscore_; - Real linelength; - - /* *************** */ - - Break_algorithm(PScore&); - - /// check if the spacing/breaking problem is well-stated - void problem_OK()const; - - /// search all pcols which are breakable. - Line_of_cols find_breaks() const; - - /// helper: solve for the columns in #curline#. - Col_hpositions solve_line(Line_of_cols) const; - - /// does curline fit on the paper? - bool feasible(Line_of_cols)const; - - virtual Array solve()=0; -}; - -/// wordwrap type algorithm: move to next line if current is optimal. -struct Word_wrap : Break_algorithm { - virtual Array solve(); - Word_wrap(PScore&); -}; -#endif // BREAK_HH - diff --git a/hdr/class-name.hh b/hdr/class-name.hh deleted file mode 100644 index 26da52dc0e..0000000000 --- a/hdr/class-name.hh +++ /dev/null @@ -1,19 +0,0 @@ -/* - class-name.hh -- declare - - source file of the LilyPond music typesetter - - (c) 1997 Han-Wen Nienhuys -*/ - - -#ifndef CLASS_NAME_HH -#define CLASS_NAME_HH - -/// a macro to declare the classes name as a static and virtual function. -#define NAME_MEMBERS(c) \ -static const char *static_name(){ return #c; }\ -virtual const char *name() const{ return c::static_name(); } \ -int a_stupid_nonexistent_function_to_allow_the_semicolon_come_out() - -#endif // CLASS-NAME_HH diff --git a/hdr/clef-item.hh b/hdr/clef-item.hh deleted file mode 100644 index 341204f8ea..0000000000 --- a/hdr/clef-item.hh +++ /dev/null @@ -1,31 +0,0 @@ - -/* - clef-item.hh -- declare Clef_item - - (c) 1996,97 Han-Wen Nienhuys -*/ - -#ifndef CLEFITEM_HH -#define CLEFITEM_HH -#include "item.hh" - - -struct Clef_item : Item { - String type; - int y_off; - - /// is this a change clef (smaller size)? - bool change; - - - /* *************** */ -NAME_MEMBERS(Clef_item); - Clef_item(); - void read(Clef_register const&); - void read(String); - Molecule* brew_molecule_p()const; -}; - -#endif // CLEFITEM_HH - - diff --git a/hdr/clef-reg.hh b/hdr/clef-reg.hh deleted file mode 100644 index cc3a8a90e9..0000000000 --- a/hdr/clef-reg.hh +++ /dev/null @@ -1,34 +0,0 @@ -/* - clef.hh -- part of LilyPond - - (c) 1996,97 Han-Wen Nienhuys -*/ - -#ifndef CLEF_HH -#define CLEF_HH - -#include "scalar.hh" -#include "varray.hh" -#include "register.hh" - -/// where is c-0 in the staff? -class Clef_register : public Request_register { - Clef_item *clef_p_; - Clef_change_req * clef_req_l_; - -public: - int c0_position_i_; - String clef_type_str_; - - /* ************** */ - virtual void process_requests(); - virtual void pre_move_processing(); - virtual void post_move_processing(); - virtual bool try_request(Request*); - Clef_register(); - NAME_MEMBERS(Clef_register); - void read_req(Clef_change_req*); - bool set_type(String); -}; -#endif // CLEF_HH - diff --git a/hdr/colhpos.hh b/hdr/colhpos.hh deleted file mode 100644 index 5398417ab1..0000000000 --- a/hdr/colhpos.hh +++ /dev/null @@ -1,29 +0,0 @@ -/* - colhpos.hh -- part of LilyPond - - (c) 1997 Han-Wen Nienhuys -*/ - -#ifndef COLHPOS_HH -#define COLHPOS_HH -#include "varray.hh" -#include "proto.hh" - -typedef Array Line_of_cols; - -struct Col_hpositions { - Line_of_cols cols; - Array config; - Real energy; - - /* ************** */ - void OK()const; - - Col_hpositions(); - void add( PCol*c); - void print() const; -}; - - -#endif // COLHPOS_HH - diff --git a/hdr/commandrequest.hh b/hdr/commandrequest.hh deleted file mode 100644 index 71b8331661..0000000000 --- a/hdr/commandrequest.hh +++ /dev/null @@ -1,117 +0,0 @@ -/* - commandrequest.hh -- declare Non musical requests - - source file of the LilyPond music typesetter - - (c) 1997 Han-Wen Nienhuys -*/ - - -#ifndef COMMANDREQUEST_HH -#define COMMANDREQUEST_HH - -#include "request.hh" -#include "varray.hh" - -/** Request which are assumed to be "happening" before the - musical requests. */ -struct Command_req : virtual Request { - REQUESTMETHODS(Command_req, command); - - virtual Measure_grouping_req * measuregrouping() { return 0; } - virtual Clef_change_req * clefchange() { return 0; } - virtual Key_change_req * keychange() { return 0; } - virtual Partial_measure_req * partial() { return 0; } - virtual Meter_change_req * meterchange() { return 0; } - virtual Bar_req *bar() { return 0; } - virtual Cadenza_req *cadenza() { return 0; } - virtual Timing_req*timing() { return 0; } -}; - - -/** Baseclass for meter/partial req. It has to be handled by - Staff_{walker,column} baseclass. */ -struct Timing_req : Command_req { - REQUESTMETHODS(Timing_req, timing); -}; - - -struct Partial_measure_req : Timing_req { - Moment duration_; - - Partial_measure_req(Moment); - REQUESTMETHODS(Partial_measure_req, partial); -}; - -/** - todo: allow C meter - */ -struct Meter_change_req : Timing_req { - int beats_i_, one_beat_i_; - - Meter_change_req(); - void set(int,int); - REQUESTMETHODS(Meter_change_req, meterchange); -}; - -/// toggle Cadenza mode -struct Cadenza_req : Timing_req { - /// turn on? - bool on_b_; - Cadenza_req(bool); - REQUESTMETHODS(Cadenza_req,cadenza); -}; - -/// check if we're at start of a measure. -struct Barcheck_req : Timing_req { - - REQUESTMETHODS(Barcheck_req,barcheck); -}; - -struct Measure_grouping_req: Timing_req { - Array beat_i_arr_; - Array elt_length_arr_; - - REQUESTMETHODS(Measure_grouping_req, measuregrouping); -}; - -struct Group_change_req : Command_req { - String newgroup_str_; - REQUESTMETHODS(Group_change_req, groupchange); -}; - -/** draw a (repeat)-bar. This something different than #Barcheck_req#, - the latter should only happen at the start of a measure. */ -struct Bar_req : Command_req { - String type_str_; - Bar_req(String); - int compare(const Bar_req&)const; - REQUESTMETHODS(Bar_req,bar); -}; -struct Terminate_voice_req : Command_req { - REQUESTMETHODS(Terminate_voice_req,terminate); -}; - -struct Group_feature_req : Command_req { - int stemdir_i_; - Group_feature_req(); - REQUESTMETHODS(Group_feature_req, groupfeature); -}; - - -struct Key_change_req : Command_req { - Array melodic_p_arr_; - - Key_change_req(); - Key_change_req(Key_change_req const&); - ~Key_change_req(); - REQUESTMETHODS(Key_change_req, keychange); -}; - -struct Clef_change_req : Command_req { - String clef_str_; - Clef_change_req(String); - REQUESTMETHODS(Clef_change_req, clefchange); -}; - -#endif // COMMANDREQUEST_HH diff --git a/hdr/complex-staff.hh b/hdr/complex-staff.hh deleted file mode 100644 index 0a37e3a5f7..0000000000 --- a/hdr/complex-staff.hh +++ /dev/null @@ -1,25 +0,0 @@ -/* - complex-staff.hh -- declare Complex_staff - - (c) 1996,1997 Han-Wen Nienhuys -*/ - -#ifndef COMPLEXSTAF_HH -#define COMPLEXSTAF_HH - - -#include "key.hh" -#include "staff.hh" -#include "staff-walker.hh" - -/// -struct Complex_staff : Staff { - - /* *************** */ - - virtual void set_output(PScore *); - virtual Staff_walker *get_walker_p(); -}; - -#endif // COMPLEXSTAF_HH - diff --git a/hdr/complex-walker.hh b/hdr/complex-walker.hh deleted file mode 100644 index 861cee77f8..0000000000 --- a/hdr/complex-walker.hh +++ /dev/null @@ -1,47 +0,0 @@ -/* - complex-walker.hh -- declare Complex_walker - - (c) 1996,97 Han-Wen Nienhuys -*/ - -#ifndef COMPLEXWALKER_HH -#define COMPLEXWALKER_HH - -#include "proto.hh" -#include "staff-walker.hh" -#include "staff-elem-info.hh" - -/** - A staff walker which uses registers to decide what to print - */ -class Complex_walker: public Staff_walker { - bool try_command_request(Command_req *req_l); - void do_announces(); - void try_request(Request*req); - - - -public: - int c0_position_i_; - Walker_registers *walk_regs_p_; - - /* *************** */ - - void regs_process_requests(); - void typeset_element(Staff_elem *elem_p); - void announce_element(Staff_elem_info); - virtual void process_requests(); - virtual void do_post_move(); - virtual void do_pre_move(); - - Complex_walker(Complex_staff*); - ~Complex_walker(); - - Complex_staff *staff(); -private: -}; - - -#endif // COMPLEXWALKER_HH - - diff --git a/hdr/const.hh b/hdr/const.hh deleted file mode 100644 index 9c2f3f9ccc..0000000000 --- a/hdr/const.hh +++ /dev/null @@ -1,12 +0,0 @@ -/* - global constants - */ -#ifndef CONST_HH -#define CONST_HH -#include -#include "real.hh" - -const Real EPS=1e-7; // qlpsolve.hh -const int MAXITER=100; // qlpsolve.hh -const Real INFTY=HUGE_VAL; -#endif diff --git a/hdr/debug.hh b/hdr/debug.hh deleted file mode 100644 index 92715dbfdc..0000000000 --- a/hdr/debug.hh +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef DEBUG_HH -#define DEBUG_HH - -#include -#include -#include "dstream.hh" -#include "real.hh" -#include "proto.hh" - -void message( String message_str, char const* context_ch_c_l ); -void warning( String message_str, char const* context_ch_c_l ); -void error( String message_str, char const* context_ch_c_l ); -void error(String s); // errors -void error_t(const String& s, Time_description const & t_tdes); -void error_t(String const &s, const Moment &when); -// warnings -//void warning(String s); -#define WARN warnout << "warning: "<<__FUNCTION__ << "(): " -extern ostream &warnout ; - -// progress -extern ostream *mlog; - -// debugging -extern Dstream *monitor; // monitor - -#ifdef NPRINT -#define mtor if (0) *monitor // clever hack -#else -#define mtor if (check_debug) monitor->identify_as(__PRETTY_FUNCTION__) -#endif - -extern bool check_debug; - -#endif diff --git a/hdr/dimen.hh b/hdr/dimen.hh deleted file mode 100644 index a3f4e8876b..0000000000 --- a/hdr/dimen.hh +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef DIMEN_HH -#define DIMEN_HH - -#include "real.hh" -#include "string.hh" - -const Real INCH_TO_PT=72.0; -const Real CM_TO_PT=INCH_TO_PT/2.54; -const Real MM_TO_PT=CM_TO_PT/10; -const Real PT_TO_PT =1.0; - -#define PT *PT_TO_PT -#define MM *MM_TO_PT -#define CM *CM_TO_PT -#define INCH *INCH_TO_PT - -Real parse_dimen(String); -String print_dimen(Real); -Real convert_dimen(Real, String); -#endif - diff --git a/hdr/directional-spanner.hh b/hdr/directional-spanner.hh deleted file mode 100644 index 9399b71c4d..0000000000 --- a/hdr/directional-spanner.hh +++ /dev/null @@ -1,26 +0,0 @@ -/* - directional-spanner.hh -- part of LilyPond - - (c) 1996,97 Han-Wen Nienhuys -*/ - -#ifndef DIRECTIONALSPANNER_HH -#define DIRECTIONALSPANNER_HH - -#include "spanner.hh" - -/// a spanner which can be pointing "up" or "down" -struct Directional_spanner : Spanner{ - - /// -1 below heads, +1 above heads. - int dir_i_; - - /// offset of "center" relative to left-column/0-pos of staff - virtual Offset center() const=0; - virtual void set_default_dir()=0; - Directional_spanner(); - -}; - -#endif // DIRECTIONALSPANNER_HH - diff --git a/hdr/duration.hh b/hdr/duration.hh deleted file mode 100644 index ff92cf23f3..0000000000 --- a/hdr/duration.hh +++ /dev/null @@ -1,111 +0,0 @@ -// -// duration.hh -- declare Duration, Plet, Duration_convert Duration_iterator -// -// copyright 1997 Jan Nieuwenhuizen - -// split into 4? - -#ifndef DURATION_HH -#define DURATION_HH - -/// (dur) -struct Duration { - // actually i hate it when other people use default arguments, - // because it makes you easily loose track of what-s really - // happening; in the routine-s implementation you-re not aware - // of this defaultness (who sets this stupid value?). - Duration( int type_i = 1, int dots_i = 0, Plet* plet_p = 0 ); - Duration( Duration const& dur_c_r ); - ~Duration(); - - Duration const& operator =( Duration const& dur_c_r ); - - void set_plet( Plet* plet_l ); // handiger: newt zelf - -// int i_; // balltype -> type! - int type_i_; - int dots_i_; - Plet* plet_p_; -}; - -/// (plet) -struct Plet { - Plet( int replace_i, int type_i ); - Plet( Plet const& plet_c_r ); - -// int i_; - int iso_i_; // 2/3; 2 is not duration, maar of count! - int type_i_; -}; - -/** - Duration_convert handles all conversions to -n fro Duration (dur). - That is including (integer + division) representation for MIDI, - and conversion from unexact time representation (best guess :-). - - A Moment (mom) is a Rational that holds the time fraction - compared to a whole note (before also called wholes). - - SUGGESTION: currently a moment in time is called moment too; - let-s typedef Rational When too, so that we get - When Staff_column::when(), Moment Voice_element::mom(). -*/ -struct Duration_convert { - /// Most used division in MIDI, all fine with me. - static int const division_1_c_i = 384; - - /// Return (integer, division) representation. - static int dur2_i( Duration dur, int division_1_i = division_1_c_i ); - - /// Return Moment representation (fraction of whole note). - static Moment dur2_mom( Duration dur ); - - /// Return Mudela string representation. - static String dur2_str( Duration dur ); - - /// Return Moment from (integer, division) representation. - static Moment i2_mom( int i, int division_1_i = division_1_c_i ); - - /// Return Moment (fraction of whole) representation, best guess. - static Duration mom2_dur( Moment mom ); - - /// Return plet factor (not a Moment: should use Rational?). - static Moment plet_factor_mom( Duration dur ); - - /** Return synchronisation factor for mom, so that - mom2_dur( mom / sync_f ) will return the duration dur. - */ - static Real sync_f( Duration dur, Moment mom ); -}; - -/// (iter_dur) -struct Duration_iterator { - /// start at shortest: 128:2/3 - Duration_iterator(); - - // **** what about these three here ? - /// return forward_dur(); - Duration operator ++(int); - - /// return ok() - operator bool(); - - /// return dur() - Duration operator ()(); - // **** - - /// return current dur - Duration dur(); - - /// return dur(), step to next - Duration forward_dur(); - - /// durations left? - bool ok(); - -private: - Duration cursor_dur_; -}; - -#endif // DURATION_HH - diff --git a/hdr/glob.hh b/hdr/glob.hh deleted file mode 100644 index 7b8bb557d4..0000000000 --- a/hdr/glob.hh +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef GLOB_HH -#define GLOB_HH -#include -#include -#include "real.hh" - -#include "proto.hh" -#include "const.hh" -#endif diff --git a/hdr/grouping.hh b/hdr/grouping.hh deleted file mode 100644 index 06b4421b0a..0000000000 --- a/hdr/grouping.hh +++ /dev/null @@ -1,62 +0,0 @@ -/* - grouping.hh -- part of LilyPond - - (c) 1996,97 Han-Wen Nienhuys -*/ - -#ifndef GROUPING_HH -#define GROUPING_HH - -#include "moment.hh" -#include "interval.hh" -#include "varray.hh" - -typedef Interval_t MInterval; - -/** data structure which represents rhythmic units this is a tree. It groupes notes according to rules - */ -struct Rhythmic_grouping { - Array children; - MInterval *interval_; - - /* *************** */ - - Array intervals(); - MInterval interval()const; - Moment length() const; - void intersect(MInterval); - - void operator=(Rhythmic_grouping const&); - Rhythmic_grouping(Rhythmic_grouping const&); - Rhythmic_grouping(MInterval, int n=1); - Rhythmic_grouping(); - Rhythmic_grouping(Array); - ~Rhythmic_grouping(); - - void add_child(Moment start, Moment len); - bool child_fit_query(Moment start); - void split(Rhythmic_grouping r); - void split(Array); - void split(int n); - - void print() const; - void OK() const; - - Array generate_beams(Array, int&); - - /** multiply self to span #i#. - In implementation, this isn't really const, but conceptually it is. - */ - void extend(MInterval i) const; - void translate(Moment); -private: - void init(); - void junk(); - void copy(Rhythmic_grouping const&); -}; - - -Rhythmic_grouping parse_grouping(Array beat_i_arr, Array elt_length_arr); - - -#endif diff --git a/hdr/headreg.hh b/hdr/headreg.hh deleted file mode 100644 index eaa2d6f9d7..0000000000 --- a/hdr/headreg.hh +++ /dev/null @@ -1,28 +0,0 @@ -/* - headreg.hh -- part of LilyPond - - (c) 1997 Han-Wen Nienhuys -*/ - - -#ifndef HEADREG_HH -#define HEADREG_HH -#include "register.hh" - -struct Notehead_register : Request_register { - Item* note_p_; - Rhythmic_req * note_req_l_; - int dir_i_; - - /* *************** */ - Notehead_register(); - virtual bool try_request(Request *req_l) ; - virtual void process_requests(); - virtual void pre_move_processing(); - virtual void post_move_processing(); - void set_feature(Features); - NAME_MEMBERS(Notehead_register); -}; - - -#endif // HEADREG_HH diff --git a/hdr/idealspacing.hh b/hdr/idealspacing.hh deleted file mode 100644 index 05f58ba9c8..0000000000 --- a/hdr/idealspacing.hh +++ /dev/null @@ -1,30 +0,0 @@ -/* - idealspacing.hh -- part of LilyPond - - (c) 1996,97 Han-Wen Nienhuys -*/ - -#ifndef IDEALSPACING_HH -#define IDEALSPACING_HH -#include "proto.hh" - -/// ideal spacing between two columns -struct Idealspacing { - - /// the ideal distance - Real space; - - /// Hooke's constant: how strong are the "springs" attached to columns - Real hooke; - - /// the two columns - const PCol *left, *right; - - void print()const; - void OK() const ; - Idealspacing(const PCol *left,const PCol *right); -}; - - -#endif // IDEALSPACING_HH - diff --git a/hdr/identifier.hh b/hdr/identifier.hh deleted file mode 100644 index 1aa7f7d0c4..0000000000 --- a/hdr/identifier.hh +++ /dev/null @@ -1,42 +0,0 @@ - -/* - identifier.hh -- part of LilyPond - - (c) 1996,97 Han-Wen Nienhuys -*/ - -#ifndef IDENTIFIER_HH -#define IDENTIFIER_HH -#include "identparent.hh" -#include "symtable.hh" -#include "input-staff.hh" -#include "input-music.hh" -#include "notename.hh" -#include "lookup.hh" -#include "script-def.hh" - -#define make_id_class(Idclass, Class, accessor) \ -struct Idclass : Identifier {\ - virtual const char *classname() { return #Class; }\ - Idclass(String s, Class*st):Identifier(s) { data = st; }\ - virtual Class* accessor(bool copy) {\ - if (copy)\ - return new Class(* (Class*) data);\ - else\ - return (Class*) data;\ - }\ - ~Idclass() { delete accessor(false); }\ - virtual void do_print()const; \ -}\ - -make_id_class(Real_id, Real, real); -make_id_class(Script_id, Script_def, script); -make_id_class(Lookup_id, Lookup, lookup); -make_id_class(Symtables_id, Symtables, symtables); -make_id_class(Staff_id, Input_staff, staff); -make_id_class(M_chord_id, Music_general_chord, mchord); -make_id_class(M_voice_id, Music_voice, mvoice); -make_id_class(Notetab_id, Notename_tab, notename_tab); - -#endif // IDENTIFIER_HH - diff --git a/hdr/identparent.hh b/hdr/identparent.hh deleted file mode 100644 index 3e6d566ee7..0000000000 --- a/hdr/identparent.hh +++ /dev/null @@ -1,45 +0,0 @@ -/* - identparent.hh -- part of LilyPond - - (c) 1996,97 Han-Wen Nienhuys -*/ - -#ifndef IDENTPARENT_HH -#define IDENTPARENT_HH - -#include "proto.hh" -#include "string.hh" - -/* boolean argument to accesor is copy_b..*/ -#define IDACCESSOR( Input_staff, staff)\ - virtual Input_staff * staff(bool) { error(#Input_staff); return 0; } - -struct Identifier { - void *data; - String name; - - Identifier(String n) : name(n) { } - virtual ~Identifier() {} - - void print()const; - virtual const char*classname() { return "new Identifier"; } - void error(String); - IDACCESSOR(Input_staff, staff) - IDACCESSOR(Input_music, music) - IDACCESSOR(Music_voice, mvoice) - IDACCESSOR(Script_def, script) - IDACCESSOR(Symtables, symtables) - IDACCESSOR(Music_general_chord, mchord) - IDACCESSOR(Lookup,lookup) - IDACCESSOR(Real,real) - IDACCESSOR(Notename_tab, notename_tab) -protected: - virtual void do_print()const=0; -private: - Identifier(Identifier const&){} - -}; -#endif // IDENTPARENT_HH - - - diff --git a/hdr/input-file.hh b/hdr/input-file.hh deleted file mode 100644 index a01ea75076..0000000000 --- a/hdr/input-file.hh +++ /dev/null @@ -1,28 +0,0 @@ -/* - input-file.hh -- declare Input_file - - source file of the LilyPond music typesetter - - (c) 1997 Han-Wen Nienhuys -*/ - -#ifndef INPUT_FILE_HH -#define INPUT_FILE_HH -#include -#include "proto.hh" -#include "fproto.hh" -#include "varray.hh" -#include "string.hh" - -struct Input_file { - istream* is; - char const* defined_ch_c_l_; - Source_file* sourcefile_l_; - int line; - String name; - - Input_file(String); - ~Input_file(); -}; - -#endif // INPUT_FILE_HH diff --git a/hdr/input-music.hh b/hdr/input-music.hh deleted file mode 100644 index 1d7a8caa66..0000000000 --- a/hdr/input-music.hh +++ /dev/null @@ -1,140 +0,0 @@ -/* - input-music.hh -- part of LilyPond - - (c) 1996,97 Han-Wen Nienhuys -*/ - -#ifndef INPUTMUSIC_HH -#define INPUTMUSIC_HH - -#include "plist.hh" -#include "proto.hh" -#include "voice.hh" -#include "moment.hh" - -struct Voice_list : public PointerList { - void translate_time(Moment dt); -}; - -/** - - A set voices. - Input_music is anything that can simply be regarded as/converted to - a set of voices "cooperating" or independant. It has some basic - characteristics that real music has too: - - - it is rhythmic (it has a length, and can be translated horizontally) - - a pitch (it can be transposed) - - */ -struct Input_music { - virtual Voice_list convert()const=0; - void check_plet(Voice_element* velt_l); - virtual Moment length()const=0; - virtual void translate_time(Moment dt)=0; - virtual ~Input_music(){} - virtual void print() const =0; - virtual void set_default_group(String)=0; - virtual bool find_plet_start_bo(char c, Moment& moment_r) = 0; - virtual void set_plet_backwards(Moment& now_moment_r, Moment until_moment, int num_i, int den_i) = 0; - // virtual void transpose(...) const =0; - - - virtual Input_music *clone() const = 0; - virtual Simple_music *simple() { return 0; } -}; - -/// Simple music consists of one voice -struct Simple_music : Input_music { - Voice voice_; - - /* *** */ - virtual Simple_music*simple() { return this; } - void add(Voice_element*); - virtual void set_default_group(String g) { voice_.set_default_group(g); } - virtual Moment length()const; - virtual Voice_list convert()const; - virtual void translate_time(Moment dt); - virtual void print() const; - virtual bool find_plet_start_bo(char c, Moment& moment_r); - virtual void set_plet_backwards(Moment& now_moment_r, Moment until_moment, int num_i, int den_i); - virtual Input_music *clone() const { - return new Simple_music(*this); - } - -}; - -/// Complex_music consists of multiple voices -struct Complex_music : Input_music { - IPointerList elts; - /* *************** */ - virtual void set_default_group(String g); - void add(Input_music*); - Complex_music(); - Complex_music(Complex_music const &); - virtual void print() const ; - void concatenate(Complex_music*); - virtual bool find_plet_start_bo(char c, Moment& moment_r); - virtual void set_plet_backwards(Moment& now_moment_r, Moment until_moment, int num_i, int den_i); - -}; - - -/** - A voice like list of music. - - different music forms which start after each other ( concatenated, - stacked "horizontally ) - - */ - -struct Music_voice : Complex_music { - - - /* *************** */ - Moment length()const; - virtual void translate_time(Moment dt); - virtual Voice_list convert()const; - void add_elt(Voice_element*); - virtual Input_music *clone() const { - return new Music_voice(*this); - } - virtual void print() const ; -}; - -/** - Multiple musicstuff stacked on top of each other - chord like : - - - different music forms which start at the same time ( stacked "vertically" ) - - */ -struct Music_general_chord : Complex_music { - - - /* *************** */ - - virtual Moment length()const; - virtual Voice_list convert()const; - virtual void translate_time(Moment dt); - void add_elt(Voice_element*); - virtual Input_music *clone() const { - return new Music_general_chord(*this); - } - - virtual void print() const ; -}; - -struct Multi_voice_chord : Music_general_chord { - void set_default_group(String); - virtual Input_music *clone() const { - return new Multi_voice_chord(*this); - } -}; -struct Voice_group_chord : Music_general_chord { - - virtual Input_music *clone() const { - return new Voice_group_chord(*this); - } -}; -#endif // INPUTMUSIC_HH diff --git a/hdr/input-score.hh b/hdr/input-score.hh deleted file mode 100644 index 4286f4b60b..0000000000 --- a/hdr/input-score.hh +++ /dev/null @@ -1,46 +0,0 @@ -/* - input-score.hh -- declare - - source file of the LilyPond music typesetter - - (c) 1997 Han-Wen Nienhuys -*/ - - -#ifndef INPUTSCORE_HH -#define INPUTSCORE_HH - -#include "varray.hh" -#include "proto.hh" -#include "plist.hh" -#include "string.hh" - - -/// the total music def of one movement -struct Input_score { - /// defined where? - const char* defined_ch_c_l_; - int errorlevel_i_; - - /// paper_, staffs_ and commands_ form the problem definition. - Paper_def *paper_p_; - Midi_def* midi_p_; - IPointerList staffs_; - - Input_music * score_wide_music_p_; - - /* *************************************************************** */ - Input_score(); - Input_score(Input_score const&); - - void add(Input_staff*); - ~Input_score(); - /// construction - void set(Paper_def*); - void set(Midi_def* midi_p); - void print() const; - Score*parse(); - void set(Input_music*); -}; - -#endif diff --git a/hdr/input-staff.hh b/hdr/input-staff.hh deleted file mode 100644 index 3b874a1b39..0000000000 --- a/hdr/input-staff.hh +++ /dev/null @@ -1,35 +0,0 @@ -/* - input-staff.hh -- declare Input_staff - - (c) 1996,97 Han-Wen Nienhuys -*/ - -#ifndef INPUTSTAFF_HH -#define INPUTSTAFF_HH - -#include "string.hh" -#include "plist.hh" -#include "varray.hh" -#include "proto.hh" - -struct Input_staff { - - const char * defined_ch_c_l_; - String type; - - IPointerList music_; - Input_music * score_wide_music_p_; - - /* *************** */ - ~Input_staff(); - void add(Input_music*m); - Input_staff(Input_staff const&); - Input_staff(String); - void set_score_wide(Input_music*m); - Staff* parse(Score*, Input_music *score_wide); - void print() const; -}; - - -#endif // INPUTSTAFF_HH - diff --git a/hdr/item.hh b/hdr/item.hh deleted file mode 100644 index d1fc8c8bfa..0000000000 --- a/hdr/item.hh +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef ITEM_HH -#define ITEM_HH - -#include "glob.hh" -#include "boxes.hh" -#include "string.hh" -#include "staff-elem.hh" - -/** - a horizontally fixed size element of the score - - Item is the datastructure for printables whose width is known - before the spacing is calculated - - NB. This doesn't mean an Item has to initialize the output field before - spacing calculation. - -*/ -struct Item : Staff_elem { - /// indirection to the column it is in - PCol * pcol_l_; - - /* *************** */ - virtual Item *item() { return this; } - Item(); - void do_print()const; - - NAME_MEMBERS(Item); -}; - - -#endif diff --git a/hdr/key-item.hh b/hdr/key-item.hh deleted file mode 100644 index e56af8e682..0000000000 --- a/hdr/key-item.hh +++ /dev/null @@ -1,31 +0,0 @@ -/* - key-item.hh -- part of LilyPond - - (c) 1996,97 Han-Wen Nienhuys -*/ - -#ifndef KEYITEM_HH -#define KEYITEM_HH - -#include "item.hh" -#include "varray.hh" - - -/// An item which places accidentals at the start of the line -struct Key_item : Item { - Array pitch; - Array acc; - int c_position; - - - /* *************** */ -NAME_MEMBERS(Key_item); - Key_item(int cposition); - void add(int pitch, int acc); - void read(const Key_register&); - void set_c_position(int); - void preprocess(); - Molecule* brew_molecule_p()const; -}; - -#endif // KEYITEM_HH diff --git a/hdr/key-reg.hh b/hdr/key-reg.hh deleted file mode 100644 index d8a96d066e..0000000000 --- a/hdr/key-reg.hh +++ /dev/null @@ -1,35 +0,0 @@ -/* - key-reg.hh -- declare Key_register - - source file of the LilyPond music typesetter - - (c) 1997 Han-Wen Nienhuys -*/ - - -#ifndef KEYREG_HH -#define KEYREG_HH - -#include "register.hh" -#include "key.hh" - -struct Key_register : Request_register { - Key key_; - Key_change_req * keyreq_l_; - Key_item * kit_p_; - Array accidental_idx_arr_; - bool default_key_b_; - - virtual bool try_request(Request *req_l); - virtual void process_requests(); - virtual void pre_move_processing(); - virtual void post_move_processing(); - virtual void acknowledge_element(Staff_elem_info); - Key_register(); - NAME_MEMBERS(Key_register); -private: - - void read_req(Key_change_req * r); -}; - -#endif // KEYREG_HH diff --git a/hdr/key.hh b/hdr/key.hh deleted file mode 100644 index 3d58629d5d..0000000000 --- a/hdr/key.hh +++ /dev/null @@ -1,39 +0,0 @@ -/* - key.hh -- declare Key - - (c) 1996,97 Han-Wen Nienhuys -*/ - -#ifndef KEY_HH -#define KEY_HH - -#include "varray.hh" -#include "scalar.hh" - -/// administration of current key -class Key { - Array accidental_i_arr_; - - /* *************** */ - -public: - - Key(); - void set(int i, int acc); - int acc(int i)const { return accidental_i_arr_[i]; } -}; - -/// administration of accidentals -struct Local_key -{ - void reset(Key); - Key& oct(int); - Local_key(); - -private: - Array octaves; -}; - -#endif // KEY_HH - - diff --git a/hdr/keyword.hh b/hdr/keyword.hh deleted file mode 100644 index 152d9dc15d..0000000000 --- a/hdr/keyword.hh +++ /dev/null @@ -1,27 +0,0 @@ -/* - keyword.hh -- part of LilyPond - - (c) 1996,97 Han-Wen Nienhuys -*/ - -#ifndef KEYWORD_HH -#define KEYWORD_HH - -/* for the keyword table */ -struct Keyword_ent -{ - const char *name; - int tokcode; -}; - -struct Keyword_table -{ - Keyword_ent *table; - int maxkey; - Keyword_table(Keyword_ent *); - int lookup(const char *s) const; -}; - - -#endif // KEYWORD_HH - diff --git a/hdr/leastsquares.hh b/hdr/leastsquares.hh deleted file mode 100644 index 35b1e1d34b..0000000000 --- a/hdr/leastsquares.hh +++ /dev/null @@ -1,24 +0,0 @@ -/* - leastsquare.hh -- part of LilyPond - - (c) 1996,97 Han-Wen Nienhuys -*/ - -#ifndef LEASTSQUARE_HH -#define LEASTSQUARE_HH -#include "varray.hh" -#include "offset.hh" - - -/** - Least squares minimisation in 2 variables. - */ -struct Least_squares { - Array input; - void minimise(Real &coef, Real &offset); - void OK() const; -}; - - -#endif // LEASTSQUARE_HH - diff --git a/hdr/lexer.hh b/hdr/lexer.hh deleted file mode 100644 index 6a9d21a98e..0000000000 --- a/hdr/lexer.hh +++ /dev/null @@ -1,51 +0,0 @@ -/* - lexer.hh -- declare My_flex_lexer - - source file of the LilyPond music typesetter - - (c) 1997 Han-Wen Nienhuys -*/ - -#ifndef LEXER_HH -#define LEXER_HH -#include -#include "proto.hh" -#include "fproto.hh" -#include "varray.hh" -#include "string.hh" - -int yylex(); -void yyerror(const char *s); -bool busy_parsing(); -void kill_lexer(); -void set_lexer(); - -/// lexer with provisions for include files. -struct My_flex_lexer : yyFlexLexer { - - Array include_stack; - Assoc *the_id_tab; - Keyword_table * keytable; - Notename_tab * defaulttab; - int errorlevel_i_; - /* *************** */ - int ret_notename(int *p, String text, int octave_mod); - char const* here_ch_c_l(); - void set(Notename_tab *n); - int lookup_keyword(String); - void lookup_notename(int &large, int &small, String s); - void LexerError(const char *); - String spot() const; - Identifier*lookup_identifier(String s); - My_flex_lexer(); - void add_identifier(Identifier*i); - ~My_flex_lexer(); - void new_input(String s); - bool close_input(); - int yylex(); - void print_declarations() const; -}; - -extern My_flex_lexer *lexer; - -#endif diff --git a/hdr/lily-stream.hh b/hdr/lily-stream.hh deleted file mode 100644 index 55ae71b6e3..0000000000 --- a/hdr/lily-stream.hh +++ /dev/null @@ -1,27 +0,0 @@ -// -// lily-stream.hh -- part of LilyPond -// -// copyright 1997 Jan Nieuwenhuizen - -// should i be named Mudela_stream? - -#ifndef LILY_STREAM_HH -#define LILY_STREAM_HH - -/// Lily output -struct Lily_stream { - ostream* os_p_; - String filename_str_; - - Lily_stream( String filename_str ); - ~Lily_stream(); - - Lily_stream& operator <<( String str ); - Lily_stream& operator <<( Midi_event& midi_event_r ); - - void header(); - void open(); -}; - -#endif // LILY_STREAM_HH - diff --git a/hdr/linespace.hh b/hdr/linespace.hh deleted file mode 100644 index 1479d1e936..0000000000 --- a/hdr/linespace.hh +++ /dev/null @@ -1,106 +0,0 @@ -#ifndef PROBLEM_HH -#define PROBLEM_HH - -#include "glob.hh" -#include "plist.hh" -#include "varray.hh" -#include "vector.hh" -#include "interval.hh" - -/// helper struct for #Spacing_problem# -struct Colinfo { - const PCol *pcol_; - const Real* fixpos; - Interval width; - - /* *************** */ - Colinfo(); - void operator=(Colinfo const&); - Colinfo(Colinfo const&); - ~Colinfo(); - Colinfo(const PCol*,const Real*); - void print() const; - bool fixed() const { return fixpos;} - Real fixed_position()const { return *fixpos; } - Real minright() const { return width.right; } - Real minleft() const { return -width.left; } -}; - - -/** the problem, given by the columns (which include constraints) and - intercolumn spacing. The problem is: - - Generate a spacing which - \begin{itemize} - \item - Satisfies spacing constraints (notes can't be printed through each other) - \item - Looks good, ie tries to conform to an ideal spacing as much as possible. - \end{itemize} - This is converted by regarding idealspacing as "springs" attached - to columns. The equilibrium of one spring is the ideal - distance. The columns have a size, this imposes "hard" constraints - on the distances. This transforms the problem into a quadratic - programming problem with linear constraints. - - The quality is given by the total potential energy in the - springs. The lower the energy, the better the configuration. -*/ -class Spacing_problem { - Array ideals; - Array cols; - - /// the index of #c# in #cols# - int col_id(const PCol *c) const; - - /// generate an (nonoptimal) solution - Vector find_initial_solution() const; - - /// check if problem is too tight - bool check_feasible() const; - - /// does #this# contain the column #w#? - bool contains(const PCol *w); - - /// make the energy function - void make_matrices(Matrix &quad, Vector &lin,Real&) const; - - /// generate the LP constraints - void make_constraints(Mixed_qp& lp) const; - -public: - /** solve the spacing problem - - @return the column positions, and the energy (last element) - - */ - Array solve() const; - - - /** - add a idealspacing to the problem. - - One pair of columns can have no, one or more idealspacings, - since they can be "summed" if the columns to which #i# refers are - not in this problem, the spacing is ignored. - */ - void add_ideal(const Idealspacing *i); - - - /** add a col to the problem. columns have to be added left to right. The column contains - info on it's minimum width. - */ - void add_column(const PCol *, bool fixed=false, Real fixpos=0.0); - - - - bool check_constraints(Vector v) const; - - Vector try_initial_solution() const; - void OK() const; - void print() const; - void print_ideal(const Idealspacing*)const; -}; - - -#endif diff --git a/hdr/local-key-item.hh b/hdr/local-key-item.hh deleted file mode 100644 index 96bad9999e..0000000000 --- a/hdr/local-key-item.hh +++ /dev/null @@ -1,33 +0,0 @@ -/* - local-key-item.hh -- part of LilyPond - - (c) 1996,97 Han-Wen Nienhuys -*/ - -#ifndef LOCALKEYITEM_HH -#define LOCALKEYITEM_HH -#include "item.hh" -#include "varray.hh" - -struct Local_acc { - int name , acc, octave; - static int compare(Local_acc&, Local_acc&); -}; - -struct Local_key_item : Item { -NAME_MEMBERS(Local_key_item); - Array accs; - Array support_items_; - int c0_position; - - /* *************** */ - - Local_key_item(int c0position); - void add(Item*); - void add(int oct, int pitch, int acc); - void add(Melodic_req*); - void do_pre_processing(); - Molecule* brew_molecule_p()const; -}; -#endif // LOCALKEYITEM_HH - diff --git a/hdr/local-key-reg.hh b/hdr/local-key-reg.hh deleted file mode 100644 index d0a2867a87..0000000000 --- a/hdr/local-key-reg.hh +++ /dev/null @@ -1,25 +0,0 @@ -/* - local-key-reg.hh -- declare Local_key_register - - (c) 1997 Han-Wen Nienhuys -*/ - - -#ifndef LOCALKEYREG_HH -#define LOCALKEYREG_HH -#include "register.hh" -#include "key.hh" - -struct Local_key_register : Request_register { - Local_key local_key_; - Local_key_item* key_item_p_; - const Key *key_c_l_; - /* *************** */ - virtual void process_requests(); - virtual void acknowledge_element(Staff_elem_info); - virtual void pre_move_processing(); - Local_key_register(); - NAME_MEMBERS(Local_key_register); -}; - -#endif // LOCALKEYREG_HH diff --git a/hdr/lookup.hh b/hdr/lookup.hh deleted file mode 100644 index 524cdf1958..0000000000 --- a/hdr/lookup.hh +++ /dev/null @@ -1,57 +0,0 @@ -/* - lilypond, (c) 1996,97 Han-Wen Nienhuys -*/ -#ifndef LOOKUPSYMS_HH -#define LOOKUPSYMS_HH - -#include "symbol.hh" -#include "fproto.hh" -#include "scalar.hh" - -/// intuitive interface to symbol table -struct Lookup { - Symtables *symtables_; - String texsetting; - /* *************** */ - void add(String, Symtable*); - void print()const; - Real internote(); - - Symbol linestaff(int n, Real w); - Symbol fill(Box b); - Symbol beam_element(int,int,Real=0); - - /// round slope to closest TeXslope - Symbol beam(Real&,Real); - - /** - pos == 3 : 3 lines above staff (extending below note) - - pos == -3: below staff - */ - Symbol streepjes(int pos); - - Symbol meter(Array); - Symbol stem(Real y1_pos, Real y2_pos); - Symbol rule_symbol(Real height, Real width); - Symbol accidental(int); - Symbol ball(int); - Symbol flag(int); - Symbol rest(int); - Symbol clef(String); - Symbol bar(String); - Symbol dots(int); - Symbol slur(int dy, Real &dx, int dir); - Symbol half_slur(int dy, Real &dx, int dir, int xpart); - Symbol half_slur_middlepart(Real &dx, int dir); - Symbol big_slur(int dy, Real &dx, int dir); - Symbol text(String style, String text, int align = 1); - Symbol script(String idx); - Symbol hairpin(Real & width, bool decresc); - - Lookup(); - Lookup(Lookup const &); - ~Lookup(); -}; - -#endif diff --git a/hdr/lyric-item.hh b/hdr/lyric-item.hh deleted file mode 100644 index dfbaf988d1..0000000000 --- a/hdr/lyric-item.hh +++ /dev/null @@ -1,19 +0,0 @@ -// -// lyric-item.hh -- part of LilyPond -// -// copyright 1997 Jan Nieuwenhuizen - -#ifndef LYRIC_ITEM_HH -#define LYRIC_ITEM_HH - -#include "textitem.hh" - -struct Lyric_item : Text_item { - /* *************** */ - Lyric_item(Lyric_req* lreq_l, int voice_count_i); - virtual void do_pre_processing(); -}; - - -#endif // LYRIC_ITEM_HH // - diff --git a/hdr/main.hh b/hdr/main.hh deleted file mode 100644 index 4a4a85e786..0000000000 --- a/hdr/main.hh +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef MAIN_HH -#define MAIN_HH -#include "proto.hh" - -void debug_init(); -void set_debug(bool); -void do_scores(); -void add_score(Input_score * s); -void set_default_output(String s); -Input_score* current_iscore_l(); -String find_file(String); -const char *get_version(); -extern Source* source_l_g; -extern bool only_midi; - -extern String default_out_fn; - -#endif diff --git a/hdr/meter-reg.hh b/hdr/meter-reg.hh deleted file mode 100644 index 6ebe18c282..0000000000 --- a/hdr/meter-reg.hh +++ /dev/null @@ -1,29 +0,0 @@ -/* - meter-reg.hh -- declare Meter_register - - source file of the LilyPond music typesetter - - (c) 1997 Han-Wen Nienhuys -*/ - - -#ifndef METERREG_HH -#define METERREG_HH -#include "register.hh" - -/** - generate meters. - */ -class Meter_register : public Request_register { -public: - Meter_change_req * meter_req_l_; - Meter * meter_p_; - - virtual bool try_request(Request *req_l); - virtual void process_requests(); - virtual void pre_move_processing(); - virtual void post_move_processing(); - Meter_register(); - NAME_MEMBERS(Meter_register); -}; -#endif // METERREG_HH diff --git a/hdr/meter.hh b/hdr/meter.hh deleted file mode 100644 index 928434b28a..0000000000 --- a/hdr/meter.hh +++ /dev/null @@ -1,22 +0,0 @@ -/* - meter.hh -- declare Meter - - (c) 1996,97 Han-Wen Nienhuys -*/ - -#ifndef METER_HH -#define METER_HH -#include "item.hh" -#include "varray.hh" -#include "scalar.hh" - -struct Meter: Item { - Array args; - /* *************** */ -NAME_MEMBERS(Meter); - - Meter(Array args) ; - Molecule*brew_molecule_p() const; -}; -#endif // METER_HH - diff --git a/hdr/midi-event.hh b/hdr/midi-event.hh deleted file mode 100644 index 06b17221aa..0000000000 --- a/hdr/midi-event.hh +++ /dev/null @@ -1,85 +0,0 @@ -// -// midi-event.hh -- declare midi_event -// -// copyright 1997 Jan Nieuwenhuizen - -#ifndef MIDI_EVENT_HH -#define MIDI_EVENT_HH - - -// should these: -// * be Midi_items -// * be Voice_elements/requests -// * get a name-change -// ? - -/// (midi_event) -class Midi_event { -public: - Midi_event(); - virtual ~Midi_event(); - - virtual String mudela_str(); // = 0; - virtual void output_mudela( Lily_stream& lily_stream_r ); - virtual Moment mom(); - -protected: - String mudela_str_; -}; - -class Midi_key : public Midi_event { -public: - Midi_key( int accidentals_i, int minor ); - virtual ~Midi_key(); - - String notename_str( int pitch_i ); - -private: - int accidentals_i_; - int minor_i_; - int key_i_; -}; - -class Midi_note : public Midi_event { - public: - int const c0_pitch_i_c_ = 60; - - Midi_note( Midi_key* midi_key_l, Midi_time* midi_time_l, int division_1_i, int pitch_i, int time_i ); - virtual ~Midi_note(); - - virtual Moment mom(); - -private: - Duration dur_; -}; - -class Midi_tempo : public Midi_event { -public: - Midi_tempo( int useconds_per_4_i ); - virtual ~Midi_tempo(); - - int get_tempo_i( Moment moment ); - -private: - int useconds_per_4_i_; - Real seconds_per_1_f_; -}; - -class Midi_time : public Midi_event { -public: - Midi_time( int num_i, int den_i, int division_4_i, int count_32_i ); - virtual ~Midi_time(); - - Duration i2_dur( int time_i, int division_1_i ); - int clocks_1_i(); - -private: - Real sync_f_; - Duration sync_dur_; - int clocks_1_i_; - int num_i_; - int den_i_; -}; - -#endif // MIDI_EVENT_HH - diff --git a/hdr/midi-item.hh b/hdr/midi-item.hh deleted file mode 100644 index 6688e95411..0000000000 --- a/hdr/midi-item.hh +++ /dev/null @@ -1,85 +0,0 @@ -// -// midi-item.hh -- part of LilyPond -// -// copyright 1997 Jan Nieuwenhuizen - -#ifndef MIDI_ITEM_HH -#define MIDI_ITEM_HH -#include "string.hh" -#include "proto.hh" - -struct Midi_item { - /* *************** */ - static String i2varint_str( int i ); - virtual void output_midi( Midi_stream& midi_stream_r ); - virtual String str() = 0; -}; - -struct Midi_note : public Midi_item { - /* *************** */ - int const c0_pitch_i_c_ = 60; - Byte dynamic_byte_; - - /** - Generate a note-event on a channel pitch. - - @param #melreq_l# is the pitch. - */ - Midi_note( Melodic_req* melreq_l, int channel_i, bool on_b ); - - virtual String str(); - - int channel_i_; - int on_b_; - int pitch_i_; -}; - -struct Midi_duration : public Midi_item { - /* *************** */ - Midi_duration( Real seconds_f ); - - virtual String str(); - - Real seconds_f_; -}; - -struct Midi_chunk : Midi_item { - /* *************** */ - Midi_chunk(); - - void add( String str ); - void set( String header_str, String data_str, String footer_str ); - virtual String str(); - -private: - String data_str_; - String footer_str_; - String header_str_; -}; - -struct Midi_header : Midi_chunk { - /* *************** */ - Midi_header( int format_i, int tracks_i, int clocks_per_4_i ); -}; - -struct Midi_tempo : Midi_item { - /* *************** */ - Midi_tempo( int tempo_i ); - - virtual String str(); - - int tempo_i_; -}; - -struct Midi_track : Midi_chunk { - /* *************** */ - int number_i_; - Midi_track( int number_i ); - - void add( int delta_time_i, String event ); -// void add( Moment delta_time_moment, Midi_item& mitem_r ); - void add( Moment delta_time_moment, Midi_item* mitem_l ); -}; - -#endif // MIDI_ITEM_HH // - diff --git a/hdr/midi-main.hh b/hdr/midi-main.hh deleted file mode 100644 index b58e077d43..0000000000 --- a/hdr/midi-main.hh +++ /dev/null @@ -1,27 +0,0 @@ -// -// midi-main.hh -- global (sic) m2m stuff -// -// copyright 1997 Jan Nieuwenhuizen -#include "string.hh" - -#define monitor_p_g &cout -enum Verbose { QUIET_ver, BRIEF_ver, NORMAL_ver, VERBOSE_ver, DEBUG_ver }; -extern Verbose level_ver; -#ifdef NPRINT -#define dtor if ( 0 ) *monitor_p_g -#define mtor if ( 0 ) *monitor_p_g -#else -#define dtor if ( level_ver >= DEBUG_ver ) *monitor_p_g -#define vtor if ( level_ver >= VERBOSE_ver ) *monitor_p_g -#define mtor if ( level_ver >= NORMAL_ver ) *monitor_p_g -#define btor if ( level_ver >= BRIEF_ver ) *monitor_p_g -#define qtor if ( level_ver >= QUIET_ver ) *monitor_p_g -#endif - -extern Source* source_l_g; -extern bool no_triplets_bo_g; -void message( String message_str, char const* context_ch_c_l ); -void warning( String message_str, char const* context_ch_c_l ); -void error( String message_str, char const* context_ch_c_l ); - -String version_str(); diff --git a/hdr/midi-output.hh b/hdr/midi-output.hh deleted file mode 100644 index a590f5a790..0000000000 --- a/hdr/midi-output.hh +++ /dev/null @@ -1,21 +0,0 @@ -/* - midi-output.hh -- declare Midi_output - - source file of the LilyPond music typesetter - - (c) 1997 Han-Wen Nienhuys -*/ - - -#ifndef MIDIOUTPUT_HH -#define MIDIOUTPUT_HH -#include "pscore.hh" - -struct Midi_output { - Midi_stream* midi_stream_l_; - Midi_output(Score* score_l, Midi_def* ); - void do_staff(Staff*st_l, int count); - - Midi_def* midi_l_; -}; -#endif // MIDIOUTPUT_HH diff --git a/hdr/midi-score.hh b/hdr/midi-score.hh deleted file mode 100644 index 68707633ef..0000000000 --- a/hdr/midi-score.hh +++ /dev/null @@ -1,27 +0,0 @@ -// -// midi-score.hh -- declare midi_score -// -// copyright 1997 Jan Nieuwenhuizen - -#ifndef MIDI_SCORE_HH -#define MIDI_SCORE_HH - -/// (midi_score) -class Midi_score { -public: - Midi_score( int format_i, int tracks_i, int tempo_i ); - ~Midi_score(); - - void add_track( Midi_track* midi_track_p ); - - int output_mudela( String filename_str ); - -private: - IPointerList midi_track_p_list_; - int format_i_; - int tracks_i_; - int tempo_i_; -}; - -#endif // MIDI_SCORE_HH - diff --git a/hdr/midi-stream.hh b/hdr/midi-stream.hh deleted file mode 100644 index 6946bfdda1..0000000000 --- a/hdr/midi-stream.hh +++ /dev/null @@ -1,32 +0,0 @@ -// -// midi-stream.hh -- part of LilyPond -// -// copyright 1997 Jan Nieuwenhuizen - -#ifndef MIDI_STREAM_HH -#define MIDI_STREAM_HH - -#include -#include "string.hh" - -/// Midi output -struct Midi_stream { - ostream* os_p_; - String filename_str_; - int clocks_per_4_i_; - int tracks_i_; - - Midi_stream( String filename_str, int tracks_i, int clocks_per_4_i_ ); - ~Midi_stream(); - - Midi_stream& operator <<( String str ); - Midi_stream& operator <<( Midi_item& mitem_r ); - Midi_stream& operator <<( int i ); - - void header(); - void open(); - -//private: -// Midi_stream(Midi_stream const&); -}; -#endif // MIDI_STREAM_HH // diff --git a/hdr/midi-track.hh b/hdr/midi-track.hh deleted file mode 100644 index d1458ed0ca..0000000000 --- a/hdr/midi-track.hh +++ /dev/null @@ -1,26 +0,0 @@ -// -// midi-track.hh -- declare midi_track -// -// copyright 1997 Jan Nieuwenhuizen - -#ifndef MIDI_TRACK_HH -#define MIDI_TRACK_HH - -/// (midi_track) -class Midi_track { -public: - Midi_track( int track_i ); - ~Midi_track(); - - void add_event( Moment mom, Midi_event* midi_event_p ); - String name_str(); - void output_mudela( Lily_stream& lily_stream_r ); - Track_column* tcol_l( Moment mom ); - -private: - IPointerList tcol_p_list_; - String name_str_; -}; - -#endif // MIDI_TRACK_HH - diff --git a/hdr/misc.hh b/hdr/misc.hh deleted file mode 100644 index 00b742076e..0000000000 --- a/hdr/misc.hh +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef MISC_HH -#define MISC_HH - -#include "proto.hh" -#include "real.hh" -#include "moment.hh" -#include "scalar.hh" -#include "grouping.hh" - -Moment wholes(int dur, int dots); -double log_2(double x) ; -int intlog2(int d); -inline int -abs(int i){ - return (i < 0)?-i:i; -} -inline int -sign(int i) { - if (i<0) return -1; - else if (i) return 1; - else return 0; -} - -Interval itemlist_width(const Array &its); - -#endif diff --git a/hdr/molecule.hh b/hdr/molecule.hh deleted file mode 100644 index 084321ce4e..0000000000 --- a/hdr/molecule.hh +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef MOLECULE_HH -#define MOLECULE_HH - -#include "proto.hh" -#include "plist.hh" -#include "boxes.hh" -#include "symbol.hh" - -/// a symbol which can be translated, and freely copied -struct Atom { - Offset off; - Symbol sym; - - /* *************** */ - - void translate(Offset o) { - off += o; - } - - /// how big is #this#? - Box extent() const; - Atom(Symbol s); - - void print() const; - - String TeXstring() const; -}; - - -/** a group of individually translated symbols. You can add molecules - to the top, to the right, etc. */ -struct Molecule { - IPointerList ats; // change to List? - - /* *************** */ - - Molecule() { } - Molecule(Atom a) { add(a) ; } - - void add_right(const Molecule &m); - void add_left(const Molecule &m); - void add_top(const Molecule &m); - void add_bottom(const Molecule &m); - void add(Molecule const &m); - void translate(Offset); - void add(Atom a) { ats.bottom().add(new Atom(a)); } - /// how big is #this#? - Box extent() const; - - String TeXstring() const; - - Molecule(const Molecule&s); - void print() const; -private: - void operator=(const Molecule&); -}; -#endif diff --git a/hdr/moment.hh b/hdr/moment.hh deleted file mode 100644 index 0037d94078..0000000000 --- a/hdr/moment.hh +++ /dev/null @@ -1,14 +0,0 @@ -/* - (c) 1996,97 Han-Wen Nienhuys -*/ - -#ifndef MOMENT_HH -#define MOMENT_HH - -#include "rational.hh" -class String; -typedef Rational Moment; - - -#endif // - diff --git a/hdr/musicalrequest.hh b/hdr/musicalrequest.hh deleted file mode 100644 index 240b72afd9..0000000000 --- a/hdr/musicalrequest.hh +++ /dev/null @@ -1,198 +0,0 @@ -/* - musicalrequests.hh -- declare Musical requests - - source file of the LilyPond music typesetter - - (c) 1997 Han-Wen Nienhuys -*/ - - -#ifndef MUSICALREQUESTS_HH -#define MUSICALREQUESTS_HH - -#include "request.hh" - - -/** - A request which is coupled to a #Voice_element# with nonzero duration. - Base class only - */ -struct Musical_req : virtual Request { - virtual Skip_req* skip() { return 0; } - REQUESTMETHODS(Musical_req, musical); -}; - - -struct Skip_req : Musical_req { - Moment duration_; - - virtual Moment duration() const; - REQUESTMETHODS(Skip_req, skip); -}; -/** a request with a duration. - This request is used only a base class. - */ -struct Rhythmic_req : virtual Musical_req { - int balltype; - int dots; - Moment plet_factor; - /* *************** */ - static int compare(const Rhythmic_req &, const Rhythmic_req &); - virtual Moment duration() const; - Rhythmic_req(); - Rhythmic_req(int,int); - REQUESTMETHODS(Rhythmic_req, rhythmic); -}; - -struct Spacing_req :virtual Request { - Moment next; - Real distance; - Real strength; - /* *************** */ - Spacing_req(); - REQUESTMETHODS(Spacing_req, spacing); -}; - -struct Blank_req : Spacing_req, Rhythmic_req { - REQUESTMETHODS(Spacing_req, spacing); - -}; - -/// Put a text above or below (?) this staff. -struct Text_req : virtual Musical_req { - /// preferred position (above/below) - int dir_i_; - /// the characteristics of the text - Text_def *tdef_p_; - /* *************** */ - Text_req(int d, Text_def*); - ~Text_req(); - Text_req(Text_req const&); - static int compare(const Text_req&,const Text_req&); - REQUESTMETHODS(Text_req,text); -}; - -/** Put a text in lyric_staff - @see Lyric_staff - */ -struct Lyric_req : public Rhythmic_req, Text_req { - Lyric_req(Text_def* t_p); - REQUESTMETHODS(Lyric_req, lreq_l); -}; - -/// request which has some kind of pitch -struct Melodic_req :virtual Musical_req -{ - /// 0 is c, 6 is b - int notename_i_; - /// 0 is central c - int octave_i_; - - /// 0 natural, 1 sharp, etc - int accidental_i_; - - /// force/supress printing of accidental. - bool forceacc_b_; - - /// return height from central c (in halflines) - int height()const; - /// return pitch from central c (in halfnotes) - int pitch()const; - Melodic_req(); - - REQUESTMETHODS(Melodic_req,melodic); -}; - -/// Put a note of specified type, height, and with accidental on the staff. -struct Note_req : Rhythmic_req, virtual Melodic_req { - - - Rhythmic_req* rhythmic() { return Rhythmic_req::rhythmic(); } - REQUESTMETHODS(Note_req, note); - }; - -/** -Put a rest on the staff. Why a request? It might be a good idea to not typeset the rest, if the paper is too crowded. -*/ -class Rest_req : public Rhythmic_req { -public: - REQUESTMETHODS(Rest_req,rest); -}; - -/** - attach a stem to the noteball. - Rhythmic_req parent needed to determine if it will fit inside a beam. - */ -struct Stem_req : Rhythmic_req { - /// preferred direction for the stem - int dir_i_; - Stem_req(int s, int dots); - REQUESTMETHODS(Stem_req,stem); -}; - -/** - Requests to start or stop something. - This type of request typically results in the creation of a #Spanner# -*/ -struct Span_req : Musical_req { - /// should the spanner start or stop, or is it unwanted? - enum { - NOSPAN, START, STOP - } spantype ; - static int compare(const Span_req &r1, const Span_req &r2); - REQUESTMETHODS(Span_req,span); - - Span_req(); - -}; - -/// request for backward plet generation -struct Plet_req : Request { - char type_c_; - int dur_i_; - int type_i_; - Plet_req(); - - REQUESTMETHODS(Plet_req,plet); -}; -/** -*/ - -/** Start / stop a beam at this note. if #nplet# is set, the staff will try to put an -appropriate number over the beam - */ -struct Beam_req : Span_req { - int nplet; - - /* *************** */ - REQUESTMETHODS(Beam_req,beam); - - Beam_req(); -}; - -/// a slur -struct Slur_req : Span_req { - REQUESTMETHODS(Slur_req,slur); - -}; - - -/**Put a script above or below this ``note''. eg upbow, downbow. Why a -request? These symbols may conflict with slurs and brackets, so this -also a request */ -struct Script_req : Musical_req { - int dir_i_; - Script_def *scriptdef_p_; - - /* *************** */ - static int compare(const Script_req &, const Script_req &); - Script_req(int d, Script_def*); - REQUESTMETHODS(Script_req,script); - ~Script_req(); - Script_req(Script_req const&); -}; - - - - -#endif // MUSICALREQUESTS_HH diff --git a/hdr/my-midi-parser.hh b/hdr/my-midi-parser.hh deleted file mode 100644 index d199bc1c4e..0000000000 --- a/hdr/my-midi-parser.hh +++ /dev/null @@ -1,54 +0,0 @@ -// -// my-midi-parser.hh -- declare My_midi_parser -// -// copyright 1997 Jan Nieuwenhuizen - -#ifndef MY_MIDI_PARSER_HH -#define MY_MIDI_PARSER_HH - -// #include "proto.hh" -// #include "string.hh" - -int yyparse(); - -/// (midi_parser) -class My_midi_parser { -public: - My_midi_parser( String filename_str ); - ~My_midi_parser(); - void add_score( Midi_score* midi_score_p ); - void error( char const* sz_l ); - int parse(); - void forward( int i ); - Moment mom(); - void note_begin( int channel_i, int pitch_i, int dyn_i ); - Midi_event* note_end_midi_event_p( int channel_i, int pitch_i, int dyn_i ); - int output_mudela( String filename_str ); - void reset(); - void set_division_4( int division_4_i ); - void set_key( int accidentals_i, int minor_i ); - void set_tempo( int useconds_i ); - void set_time( int num_i, int den_i, int clocks_i, int count_32_i ); - -private: - Int64 now_i64_; // 31 bits yields tipically about 1000 bars - - static int const CHANNELS_i = 16; - static int const PITCHES_i = 128; - Int64 running_i64_i64_a_[ CHANNELS_i ][ PITCHES_i ]; - - Midi_score* midi_score_p_; - int division_1_i_; - Midi_key* midi_key_p_; - Midi_tempo* midi_tempo_p_; - Midi_time* midi_time_p_; - - char const* defined_ch_c_l_; - int fatal_error_i_; - My_midi_lexer* midi_lexer_p_; -}; - -extern My_midi_parser* midi_parser_l_g; - -#endif // MY_MIDI_PARSER_HH - diff --git a/hdr/notehead.hh b/hdr/notehead.hh deleted file mode 100644 index d7a68e7798..0000000000 --- a/hdr/notehead.hh +++ /dev/null @@ -1,45 +0,0 @@ -/* - notehead.hh -- part of LilyPond - - (c) 1996,97 Han-Wen Nienhuys -*/ - -#ifndef NOTEHEAD_HH -#define NOTEHEAD_HH -#include "item.hh" - -/** - ball at the end of the stem -takes care of: - - * help lines - * proper placing of dots - - */ - -struct Notehead : Item { - NAME_MEMBERS(Notehead); - - int position; - /// -1 = lowest, 0 = inside, 1 = top - int extremal; - /// needed for the help-lines - int staff_size; - int dots; - int balltype; - int x_dir; - - /* *************** */ - - void set_rhythmic(Rhythmic_req *); - - /** - position of top line (5 linestaff: 8) - */ - Notehead(int staff_size); - void do_print()const; - static int compare(Notehead * const &a, Notehead *const &b) ; - Molecule* brew_molecule_p()const; -}; -#endif // NOTEHEAD_HH - diff --git a/hdr/notename.hh b/hdr/notename.hh deleted file mode 100644 index b533f4d360..0000000000 --- a/hdr/notename.hh +++ /dev/null @@ -1,24 +0,0 @@ -/* - notename.hh -- part of LilyPond - - (c) 1996,97 Han-Wen Nienhuys -*/ - -#ifndef NOTENAME_HH -#define NOTENAME_HH - -#include "string.hh" - -struct Notename_tab { - String notetab[7*5]; - - void set(int l, int s, String nm); - void lookup(int &large, int &small, String s); -}; - -void set_notename_tab(Notename_tab*n); -void lookup_notename(int &large, int &small, String s); - - -#endif // NOTENAME_HH - diff --git a/hdr/offset.hh b/hdr/offset.hh deleted file mode 100644 index e0b62bba76..0000000000 --- a/hdr/offset.hh +++ /dev/null @@ -1,38 +0,0 @@ -/* - offset.hh -- part of LilyPond - - (c) 1996,97 Han-Wen Nienhuys -*/ - -#ifndef OFFSET_HH -#define OFFSET_HH -#include "real.hh" - -/// 2d vector -struct Offset { - Real x,y; - - Offset operator+(Offset o)const { - Offset r(*this); - r+=o; - return r; - } - - Offset operator+=(Offset o) { - x+=o.x; - y+=o.y; - return *this; - } - Offset(Real ix , Real iy) { - x=ix; - y=iy; - } - Offset() { - x=0.0; - y=0.0; - } -}; - -#endif // OFFSET_HH - - diff --git a/hdr/paper-def.hh b/hdr/paper-def.hh deleted file mode 100644 index ae557258b0..0000000000 --- a/hdr/paper-def.hh +++ /dev/null @@ -1,54 +0,0 @@ -/* - paper-def.hh -- declare - - source file of the LilyPond music typesetter - - (c) 1997 Han-Wen Nienhuys -*/ - - -#ifndef Paper_def_HH -#define Paper_def_HH -#include "proto.hh" -#include "real.hh" -#include "string.hh" -#include "moment.hh" - - -/** symbols, dimensions and constants - - This struct takes care of all kinds of symbols, dimensions and - constants. Most of them are related to the point-size of the fonts, - so therefore, the lookup table for symbols is also in here. - - see TODO - */ -struct Paper_def { - Lookup *lookup_p_; - String outfile; - - Real linewidth; - - /// how much space does a whole note take (ideally?) - Real whole_width; - - /// ideal = geometric_ ^ log2(duration) - Real geometric_; - - /* *************** */ - void reinit(); - Paper_def(Lookup*); - void set(Lookup*); - ~Paper_def(); - Paper_def(Paper_def const&); - Real interline()const; - Real internote()const; - Real rule_thickness()const; - Real standard_height()const; - Real note_width() const; - void print() const; - Real duration_to_dist(Moment); -}; - -#endif // Paper_def_HH - diff --git a/hdr/parseconstruct.hh b/hdr/parseconstruct.hh deleted file mode 100644 index 7b9e3e3ec2..0000000000 --- a/hdr/parseconstruct.hh +++ /dev/null @@ -1,39 +0,0 @@ -/* - parseconstruct.hh -- part of LilyPond - - (c) 1996,97 Han-Wen Nienhuys -*/ - -#ifndef PARSECONSTRUCT_HH -#define PARSECONSTRUCT_HH - -#include "proto.hh" - -extern char const* defined_ch_c_l; -extern char const* req_defined_ch_c_l; -void set_default_duration(int *); -void last_duration(int n); -void set_duration_mode(String s); -void get_default_duration(int *); -void set_default_octave(String); -void set_plet(int,int); -Voice_element * get_note_element(String,int * ,int *); -Voice_element* get_rest_element(String,int *); -Voice_element* get_word_element(Text_def*, int*); -void add_requests( Voice_element*v, Array&req); -Request* get_request(char); -void set_text_style(String); -Script_def* get_scriptdef(char); -Text_def*get_text(String s); -Request* get_plet_request( char c, int dur_i, int type_i ); -Request*get_script_req(int d , Script_def*def); -Request*get_text_req(int d , Text_def*def); -Request* get_stemdir_req(int); - - - - -Request*get_grouping_req(Array i_arr); - -#endif // PARSECONSTRUCT_HH - diff --git a/hdr/pcol.hh b/hdr/pcol.hh deleted file mode 100644 index 4fac246e49..0000000000 --- a/hdr/pcol.hh +++ /dev/null @@ -1,86 +0,0 @@ -#ifndef COLS_HH -#define COLS_HH - -#include "glob.hh" -#include "boxes.hh" -#include "plist.hh" -#include "item.hh" - - -/** - stuff grouped vertically. - This is a class to address items vertically. It contains the data for: - \begin{itemize} - \item - unbroken score - \item - broken score - \item - the linespacing problem - \end{itemize} - */ - -struct PCol { - PointerList its; - PointerList stoppers, starters; - - - - /** prebreak is put before end of line. - if broken here, then (*this) column is discarded, and prebreak - is put at end of line, owned by Col - */ - PCol *prebreak_p_; - - /// postbreak at beginning of the new line - PCol *postbreak_p_; - - /** if this column is pre or postbreak, then this field points to - the parent. */ - PCol *daddy_l_; - - /// if lines are broken then this column is in #line# - const Line_of_score *line_l_; - - /// if lines are broken then this column x-coord #hpos# - Real hpos; - - PScore * pscore_l_; - - /* *************** */ - /// which one (left =0) - int rank() const; - - /// does this column have items - bool used_b() const; - - void add(Item *i); - - /// Can this be broken? true eg. for bars. - bool breakable_b()const; - - Interval width() const; - ~PCol(); - PCol(PCol * parent); - - /** - which col comes first?. - signed compare on columns. - - @return < 0 if c1 < c2. - */static int compare(const PCol &c1, const PCol &c2); - - - void OK() const; - void set_breakable(); - void print()const; -private: - PCol(PCol const&){} -}; - - -#include "compare.hh" -instantiate_compare(PCol &, PCol::compare); - - -#endif diff --git a/hdr/proto.hh b/hdr/proto.hh deleted file mode 100644 index 5a47fc459a..0000000000 --- a/hdr/proto.hh +++ /dev/null @@ -1,171 +0,0 @@ -/* - proto.hh -- part of LilyPond - - (c) 1996,97 Han-Wen Nienhuys -*/ - -#ifndef PROTO_HH -#define PROTO_HH - -#include "fproto.hh" -#include "real.hh" - -/// (i64) -typedef long long Int64; - -struct Absdynamic_req; -struct Accidental; -struct Atom; -struct Bar; -struct Bar_register; -struct Barcheck_req; -struct Bar_req; -struct Beam; -struct Beam_req; -struct Box; -struct Bracket_req; -struct Cadenza_req; -struct Chord; -struct Clef_change_req; -struct Clef_register; -struct Clef_item; -struct Col_hpositions; -struct Colinfo; -struct Complex_music; -struct Complex_staff; -struct Complex_walker; -struct Cresc_req; -struct Directional_spanner; -struct Decresc_req; -struct Duration; -struct Duration_iterator; -struct Durational_req; -struct Dynamic; -struct Group_change_req; -struct Group_feature_req; -struct Idealspacing; -struct Identifier; -struct Input_file; -struct Input_music; -struct Input_score; -struct Input_staff; -struct Item; -struct Key; -struct Key_register; -struct Key_change_req; -struct Key_item; -struct Keyword; -struct Keyword_table; -struct Lily_stream; -struct Line_of_score; -struct Line_of_staff; -struct Linestaff; -struct Local_key; -struct Local_key_register; -struct Local_key_item; -struct Lookup; -struct Lyric_item; -struct Lyric_req; -struct Melodic_req; -struct Measure_grouping_req; -struct Meter_change_req; -struct Meter; -struct Meter_register; -struct Midi_def; -struct Midi_duration; -struct Midi_event; -struct Midi_header; -struct Midi_item; -struct Midi_key; -struct Midi_note; -struct Midi_output; -struct Midi_pitch; -struct Midi_staff; -struct Midi_stream; -struct Midi_tempo; -struct Midi_time; -struct Midi_track; -struct Midi_walker; -struct Mixed_qp; -class My_midi_lexer; -class My_midi_parser; -class Midi_event; -class Midi_score; -class Midi_track; -struct Molecule; -struct Musical_req; -struct Music_general_chord; -struct Music_voice; -struct Command_req; -struct Note_req; -struct Notehead; -struct Notehead_register; -struct Notename_tab; -struct Offset; -struct Output; -struct PCol; -struct Plet_req; -struct Plet; -struct PScore; -struct PStaff; -struct Paper_def; -struct Partial_measure_req; -struct Rational; -struct Register_group_register; -struct Request; -struct Request_register; -struct Rest; -struct Rest_req; -struct Rhythmic_grouping; -struct Rhythmic_grouping_req; -struct Rhythmic_req; -struct Score; -struct Score_column; -struct Score_walker; -struct Script_def; -struct Script; -struct Script_register; -struct Script_req; -struct Simple_music; -struct Skip_req; -struct Slur; -struct Slur_register; -struct Slur_req; -struct Source; -struct Source_file; -struct Spacing_req ; -struct Span_req; -struct Spanner; -struct Blank_req; -struct Staff; -struct Staff_column; -struct Staff_elem; -struct Staff_elem_info; -struct Staff_symbol; -struct Staff_walker; -struct Stem; -struct Stem_req; -struct Stem_beam_register; -struct String; -struct Symbol; -struct Symtable; -struct Symtables; -struct Tex_stream; -struct Terminate_voice_req; -struct Text_item ; -struct Text_def; -struct Text_gob; -struct Text_register; -struct Text_req; -struct Timing_req; -struct Time_description; -struct Track_column; -struct Voice; -struct Voice_element; -struct Voice_group_registers; -struct Voice_list; -struct Voice_registers; -struct Voicegroup; -struct Walker_registers; -typedef Rational Moment; -#endif // PROTO_HH diff --git a/hdr/pscore.hh b/hdr/pscore.hh deleted file mode 100644 index b7ad49c0e1..0000000000 --- a/hdr/pscore.hh +++ /dev/null @@ -1,106 +0,0 @@ -// the breaking problem for a score. - -#ifndef PSCORE_HH -#define PSCORE_HH - -#include "colhpos.hh" -#include "varray.hh" -#include "pcol.hh" -#include "pstaff.hh" - - -/** all stuff which goes onto paper. notes, signs, symbols in a score can be grouped in two ways: - horizontally (staffwise), and vertically (columns). #PScore# - contains the items, the columns and the staffs. - */ - -struct PScore { - Paper_def *paper_l_; - - /// the columns, ordered left to right - IPointerList cols; - - /// the idealspacings, no particular order - IPointerList suz; - - /// the staffs ordered top to bottom - IPointerList staffs; - - /// all symbols in score. No particular order. - IPointerList its; - - /// if broken, the different lines - IPointerList lines; - - /// crescs etc; no particular order - IPointerList spanners; - - /// broken spanners - IPointerList broken_spans; - - /* *************** */ - /* CONSTRUCTION */ - - PScore(Paper_def*); - /// add a line to the broken stuff. Positions given in #config# - void set_breaking(Array); - - void add(PStaff *); - - - /** add an item. - add the item in specified containers. If breakstatus is set - properly, add it to the {pre,post}break of the pcol. - */ - void typeset_item(Item *item_p, PCol *pcol_l,PStaff*pstaf_l,int breakstatus=1); - - /// add a Spanner - void typeset_spanner(Spanner*, PStaff*); - - /// add to bottom of pcols - void add(PCol*); - void add_broken(Spanner*); - - /* INSPECTION */ - Array select_items(PStaff*, PCol*); - - /** - @return argument as a cursor of the list - */ - PCursor find_col(const PCol *)const; - - /* MAIN ROUTINES */ - void process(); - - /// last deed of this struct - void output(Tex_stream &ts); - - /* UTILITY ROUTINES */ - - /// get the spacing between c1 and c2, create one if necessary. - Idealspacing* get_spacing(PCol *c1, PCol *c2); - - /// connect c1 and c2 - void do_connect(PCol *c1, PCol *c2, Real distance_f, Real strength_f); - - /// connect c1 and c2 and any children of c1 and c2 - void connect(PCol* c1, PCol *c2, Real distance_f,Real strength_f= 1.0); - - /* STANDARD ROUTINES */ - void OK()const; - void print() const; -private: - /// before calc_breaking - void preprocess(); - - /// calculate where the lines are to be broken, and use results - void calc_breaking(); - - /// after calc_breaking - void postprocess(); - - /// delete unused columns - void clean_cols(); -}; - -#endif diff --git a/hdr/pstaff.hh b/hdr/pstaff.hh deleted file mode 100644 index 50a7f0c719..0000000000 --- a/hdr/pstaff.hh +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef PSTAFF_HH -#define PSTAFF_HH - -#include "proto.hh" -#include "plist.hh" -#include "item.hh" -#include "symbol.hh" - -/// items grouped horizontally -struct PStaff { - PScore * pscore_l_; - - - PointerList spans; - PointerList its; - - /* *************** */ - void add(Item*i); - PStaff(PScore*); - -private: - PStaff(PStaff const&); -}; - -#endif diff --git a/hdr/qlp.hh b/hdr/qlp.hh deleted file mode 100644 index ccfba72bb8..0000000000 --- a/hdr/qlp.hh +++ /dev/null @@ -1,97 +0,0 @@ -/* - qlp.hh -- declare Ineq_constrained_qp, Mixed_qp - - source file of the LilyPond music typesetter - - (c) 1997 Han-Wen Nienhuys -*/ - -#ifndef QLP_HH -#define QLP_HH - -#include "matrix.hh" - -/// inequality constrained quadratic program -class Ineq_constrained_qp { - friend class Active_constraints; - - Array cons; - Array consrhs; -public: - Matrix quad; - Vector lin; - Real const_term; - - - /** - use a KKT method to assert optimality of sol - */ - void assert_solution(Vector sol) const; - /// solve the problem using a projected gradient method - Vector solve(Vector start) const; - - /** - @return the number of variables in the problem - */ - int dim() const{ - return lin.dim(); - } - - /** - add a constraint - - - c*vars >= r - - PRE - c.dim() == dim(); - - */ - void add_inequality_cons(Vector c, double r); - - /** set up matrices to go with the problem. */ - Ineq_constrained_qp(int novars); - - /** - evaluate the quadratic function for input #v# - */ - Real eval(Vector v); - - void eliminate_var(int idx, Real value); - void OK()const; - void print() const; - -}; - - -/** - Quadratic programming with mixed linear constraints. - problem definition of a quadratic optimisation problem with linear - inequality and equality constraints - - - x^T QUAD x /2 + b^T x -*/ -class Mixed_qp :public Ineq_constrained_qp { - Array eq_cons; - Array eq_consrhs; -public: - Mixed_qp(int n); - void OK() const; - void print() const; - - Vector solve(Vector start) const; - void add_fixed_var(int i , Real value); - - - /** - add a constraint, - - c*vars == r - - PRE - c.dim()==dim(); - */ - void add_equality_cons(Vector c, double r); -}; -#endif diff --git a/hdr/qlpsolve.hh b/hdr/qlpsolve.hh deleted file mode 100644 index 7c9b8da341..0000000000 --- a/hdr/qlpsolve.hh +++ /dev/null @@ -1,91 +0,0 @@ -/* - qlpsolve.hh -- declare Active_constraints, Inactive_iter - - source file of the LilyPond music typesetter - - (c) 1997 Han-Wen Nienhuys -*/ - - -#ifndef QLPSOLVE_HH -#define QLPSOLVE_HH -#include "qlp.hh" -#include "matrix.hh" - - -/** - This class represents the set of active (binding) constraints - which can be active while the QLP algorithm is in a feasible - point. The active constraints are numbered. - If the constraints are of the form - - A^T*x >= b - - then the binding constraints are those where the >= is equality. - - */ - -class Active_constraints { - friend class Inactive_iter; - - - Matrix A,H; - Array active; - Array inactive; // actually this is a set, not an array. - const Ineq_constrained_qp *opt; - -public: - String status()const; - - Vector vec(int k) const { return opt->cons[k]; } - Real rhs(int k) const { return opt->consrhs[k]; } - - - /** drop constraint. drop constraint k from the active set. k is the index of the - constraint in #active# - - */ - void drop (int k); - - - /** add constraint j. - add constraint j to the active set j is the index of the - constraint in #inactive# - */ - void add(int j); - - /// exchange in and out. - void exchange(int in, int out) { add(in); drop (out); } - - - Vector find_active_optimum(Vector g); - - /// get lagrange multipliers. - Vector get_lagrange(Vector v); - - Active_constraints(Ineq_constrained_qp const *op); - /** construct: no constraints active, n vars. Put the equalities - into the constraints. */ - - /// check invariants - void OK(); -}; - - -/** - loop through the inactive constraints. - */ -class Inactive_iter { - int j; - Active_constraints const* ac; -public: - Inactive_iter(Active_constraints const &c) { ac=&c; j=0; } - int idx() const { return j; } - void operator ++(int) { j++; } - int constraint_id() const { return ac->inactive[j]; } - Vector vec() const { return ac->vec(constraint_id()); } - Real rhs() const { return ac->rhs(constraint_id()); } - bool ok() const { return j < ac->inactive.size(); } -}; - -#endif // QLPSOLVE_HH diff --git a/hdr/register.hh b/hdr/register.hh deleted file mode 100644 index da80db38fe..0000000000 --- a/hdr/register.hh +++ /dev/null @@ -1,107 +0,0 @@ -/* - register.hh -- part of LilyPond - - (c) 1996,1997 Han-Wen Nienhuys -*/ - -#ifndef REGISTER_HH -#define REGISTER_HH - -#include "proto.hh" -#include "varray.hh" -#include "request.hh" -#include "staff-elem-info.hh" - -/** - a struct which processes requests, and creates the #Staff_elem#s. - It may use derived classes. Hungarian postfix: register - */ -class Request_register { - friend class Register_group_register; - /** - You cannot copy a Request_register - */ - Request_register(const Request_register&){} -protected: - - /// utility - virtual Paper_def * paper() const; - - /** - try to fit the request in this register - - @return - false: not noted, not taken. - - true: request swallowed. Don't try to put the request elsewhere. - - - Default: always return false - */ - virtual bool try_request(Request *req_l); - - /// make items/spanners with the requests you got - virtual void process_requests(){} - - /** typeset any items/spanners. Default: do nothing - */ - virtual void pre_move_processing(){} - /** reset any appropriate data. Default: do nothing - */ - virtual void post_move_processing(){} - - /** - Is this request eligible to be processed? Default: return false. - */ - virtual bool acceptable_request_b(Request*) const; - - /** - typeset a "command" item. Default: pass on to daddy. - If the column is not breakable, #pre_p# and #post_p# are junked - */ - virtual void typeset_breakable_item(Item * pre_p , - Item * nobreak_p, Item * post_p); - /** - Invoke walker method to typeset element. Default: pass on to daddy. - */ - virtual void typeset_element(Staff_elem*elem_p); - - /** - take note of item/spanner - put item in spanner. Adjust local key; etc. - - Default: ignore the info - */ - virtual void acknowledge_element(Staff_elem_info) {} - /** - Announce element. Default: pass on to daddy. Utility - */ - virtual void announce_element(Staff_elem_info); - /** - Set features of the register(s). Default: ignore features. - */ - virtual void set_feature(Features){} - /** - Does this equal or contain a certain register? - */ - virtual bool contains_b(Request_register*reg_l); - /** - Get information on the staff. Default: ask daddy. - */ - virtual Staff_info get_staff_info(); - - virtual void do_print()const; -public: - /** Every Request_register (except for the 'top' which is directly - inside the Staff_walker, is a element of a group. */ - Register_group_register * daddy_reg_l_; - - Request_register(); - virtual ~Request_register(){} - NAME_MEMBERS(Request_register); - void print() const; -}; - - -#endif // REGISTER_HH - diff --git a/hdr/registergroup.hh b/hdr/registergroup.hh deleted file mode 100644 index 6d6e76a15b..0000000000 --- a/hdr/registergroup.hh +++ /dev/null @@ -1,54 +0,0 @@ -/* - registergroup.hh -- declare - - source file of the LilyPond music typesetter - - (c) 1997 Han-Wen Nienhuys -*/ - - -#ifndef REGISTERGROUP_HH -#define REGISTERGROUP_HH - - -#include "plist.hh" -#include "staff-elem-info.hh" -#include "register.hh" - -/** - Group a number of registers. Usually delegates everything to its contents. - Postfix: group - */ -class Register_group_register : public Request_register { -protected: - IPointerList reg_list_; - virtual void do_print()const; -public: - - /** - Junk #reg_l#. - - Pre: - #reg_l# is in #reg_list_# - */ - virtual void terminate_register(Request_register * reg_l); - - /** - Remove #reg_l# from the list, and return it. - */ - Request_register * get_register_p(Request_register*reg_l); - virtual void set_feature(Features i); - virtual bool acceptable_request_b(Request*); - virtual void pre_move_processing(); - virtual void post_move_processing(); - virtual void acknowledge_element(Staff_elem_info info); - virtual bool try_request(Request*); - virtual void process_requests(); - virtual ~Register_group_register(); - virtual void add(Request_register* reg_p); - virtual bool contains_b(Request_register*); -}; - -#endif // REGISTERGROUP_HH - - diff --git a/hdr/reqtodo.hh b/hdr/reqtodo.hh deleted file mode 100644 index eaed606453..0000000000 --- a/hdr/reqtodo.hh +++ /dev/null @@ -1,83 +0,0 @@ -#if 0 - - - -/**Draw a (Guitar) chord above or below this ``note''. -Why a request? -Because everything else is done in requests. -*/ -struct Chord : Request { - // don't know how this looks. -}; - - -/// for absolute dynamics -enum Loudness { - FFF, FF, F, MF, MP, P, PP, PPP -} ; - - -/** -Start/stop a bracket at this note. if #nplet# is set, the staff will -try to put an appropriate number over the bracket -*/ -struct Bracket_req : Span_req { - int nplet; // print a number over the beam. -}; - -struct Subtle_req { - Moment subtime; -}; - - -/** helper in the hierarchy. Each dynamic is bound to one note ( a - crescendo spanning multiple notes is thought to be made of two - "dynamics": a start and a stop). Dynamic changes can occur in a - smaller time than the length of its note, therefore fore each - Dynamic request carries a time, measured from the start of its - note. - - This subfield would come in handy, if mpp96 was adapted for midi - support. - - Dynamic should have been derived from request, but I don't want to - fuss with virtual baseclasses. */ - -struct Dynamic:Subtle_req { - -}; -/// do a crescendo -struct Cresc_req : Span_req, Dynamic { - -}; - -/// do a decrescendo -struct Decresc_req : Span_req, Dynamic { - -}; - -/// do a dynamic like "fff" or "mp" -struct Absdynamic_req : Request, Dynamic { - Loudness loudness; -}; - -struct Grace_req : Subtle_req { - -}; - -struct Grace_turn_req : Grace_turn { - -}; - -struct Grace_note : Melodic_req { - -}; - -struct Grace_notes { - -}; - -struct Glissando_req : Span_req { - -}; -#endif diff --git a/hdr/request.hh b/hdr/request.hh deleted file mode 100644 index 1936d5a2ab..0000000000 --- a/hdr/request.hh +++ /dev/null @@ -1,73 +0,0 @@ -/* - request.hh -- declare Request baseclasses. - - source file of the LilyPond music typesetter - - (c) 1997 Han-Wen Nienhuys -*/ - -#ifndef REQUEST_HH -#define REQUEST_HH -// LilyPond's second egg of columbus! - -#include "glob.hh" -#include "string.hh" -#include "moment.hh" -#include "class-name.hh" - -/** - a voice element wants something printed. - Hungarian postfix: req - @see lilygut manpage - */ -class Request { -public: - Voice_element*elt_l_; - char const* defined_ch_c_l_; - - /* *************** */ - Voice * voice_l(); - Request(); - Request(Request const&); - virtual ~Request(){} - - NAME_MEMBERS(Request); - virtual Request* clone() const { return new Request(*this); } - void print()const ; - - virtual Moment duration() const { return 0; } - - /* accessors for children - maybe checkout RTTI - */ - virtual Barcheck_req *barcheck() { return 0; } - virtual Note_req *note() { return 0;} - virtual Script_req *script() { return 0;} - virtual Stem_req *stem() { return 0;} - virtual Text_req*text() { return 0; } - virtual Rest_req *rest() { return 0; } - virtual Span_req *span() { return 0; } - virtual Beam_req *beam() { return 0 ; } - virtual Plet_req* plet() { return 0; } - virtual Slur_req *slur() { return 0 ; } - virtual Rhythmic_req*rhythmic() { return 0; } - virtual Lyric_req* lreq_l() { return 0; } - virtual Melodic_req *melodic() { return 0; } - virtual Terminate_voice_req *terminate() {return 0;} - virtual Group_change_req * groupchange() { return 0;} - virtual Group_feature_req * groupfeature() { return 0; } - virtual Spacing_req * spacing() { return 0; } - virtual Blank_req * blank() { return 0; } - virtual Musical_req *musical() { return 0; } - virtual Command_req * command() { return 0; } -protected: - virtual void do_print()const ; -}; - -#define REQUESTMETHODS(T,accessor) \ -virtual T * accessor() { return this;}\ -NAME_MEMBERS(T);\ -virtual Request *clone() const { return new T(*this); } \ -virtual void do_print() const - -#endif diff --git a/hdr/rest.hh b/hdr/rest.hh deleted file mode 100644 index 85c7266677..0000000000 --- a/hdr/rest.hh +++ /dev/null @@ -1,25 +0,0 @@ -/* - rest.hh -- part of LilyPond - - (c) 1996,97 Han-Wen Nienhuys -*/ - -#ifndef REST_HH -#define REST_HH -#include "item.hh" - -struct Rest : Item { - - int dots; - int balltype; - - /* *************** */ - - - Rest(int dur,int dots); - void do_print()const; -NAME_MEMBERS(Rest); - Molecule* brew_molecule_p()const; -}; -#endif - diff --git a/hdr/score-column.hh b/hdr/score-column.hh deleted file mode 100644 index e961d04920..0000000000 --- a/hdr/score-column.hh +++ /dev/null @@ -1,59 +0,0 @@ -/* - sccol.hh -- part of LilyPond - - (c) 1996,97 Han-Wen Nienhuys -*/ - -#ifndef SCCOL_HH -#define SCCOL_HH -#include "proto.hh" -#include "varray.hh" -#include "moment.hh" - - -/** - - When typesetting hasn't started on PScore yet, the columns which - contain data have a rhythmical position. Score_column is the type - with a rhythmical time attached to it. The calculation of - idealspacing is done with data in these columns. (notably: the - #durations# field) - - */ - -class Score_column { - friend class Score; - friend class Score_walker; - - bool musical_b_; - Moment when_; - void set_breakable(); -public: - /// indirection to column - PCol * pcol_l_; - - /// length of notes/rests in this column - Array durations; - - /* *************** */ - - Moment when() { return when_; } - Score_column(Moment when); - static int compare(Score_column & c1, Score_column &c2); - void add_duration(Moment ); - void preprocess(); - bool breakable_b(); - bool musical_b() { return musical_b_; } - bool used_b(); - void print() const; - - -}; - -instantiate_compare(Score_column&, Score_column::compare); - -#endif // SCCOL_HH - - - - diff --git a/hdr/score-walker.hh b/hdr/score-walker.hh deleted file mode 100644 index b3d304256e..0000000000 --- a/hdr/score-walker.hh +++ /dev/null @@ -1,37 +0,0 @@ -/* - score-walker.hh -- declare Score_walker - - source file of the LilyPond music typesetter - - (c) 1997 Han-Wen Nienhuys -*/ - - -#ifndef SCOREWALKER_HH -#define SCOREWALKER_HH -#include "pcursor.hh" -#include "proto.hh" -#include "varray.hh" - - -/** - walk through the score_columns, and while doing so, walk all staffs in a score. - */ -class Score_walker : public PCursor -{ - Score* score_l_; - /// walkers for the individual staves. - Array walker_p_arr_; - Array disallow_break_walk_l_arr; - int disallow_break_count_; - void reinit(); -public: - void allow_break(Staff_walker*w); - Score_walker(Score*); - ~Score_walker(); - Moment when(); - void operator++(int); - /// process staff walkers. - void process(); -}; -#endif // SCOREWALKER_HH diff --git a/hdr/score.hh b/hdr/score.hh deleted file mode 100644 index a865ed02f3..0000000000 --- a/hdr/score.hh +++ /dev/null @@ -1,90 +0,0 @@ -/* - score.hh -- declare Score - - source file of the LilyPond music typesetter - - (c) 1997 Han-Wen Nienhuys -*/ - - -#ifndef SCORE_HH -#define SCORE_HH - -#include "varray.hh" -#include "proto.hh" -#include "plist.hh" -#include "moment.hh" -#include "assoc.hh" -#include "string.hh" - -/// the total music def of one movement -struct Score { - /// paper_, staffs_ and commands_ form the problem definition. - Paper_def *paper_p_; - Midi_def *midi_p_; - IPointerList staffs_; - - /// "runtime" fields for setting up spacing - IPointerList cols_; - PScore *pscore_p_; - - const char *defined_ch_c_l_; - int errorlevel_i_; - - /* *************************************************************** */ - - /// construction - Score(); - ~Score(); - void add(Staff*); - - /// do everything except outputting to file - void process(); - - /// output to file - void output(String fn); - - - /// - void set(Midi_def* midi_p); - /// - void set(Paper_def* midi_p); - - // standard - void OK() const; - void print() const; - - /// find a column. - PCursor find_col(Moment,bool); - - /// when does the last *musical* element finish? - Moment last() const; - -private: - void paper_output(); - void setup_music(); - void process_music(); - /// do midi stuff - void midi(); - - /// do paper stuff - void paper(); - - // utils: - PCursor create_cols(Moment); - - Score(Score const&){} - - /** - make the pcol_l_ fields of each Score_column point to the correct PCol, - remove any unnecessary Score_column's - */ - void do_cols(); - - /// remove unused cols - void clean_cols(); - - /// add #Idealspacings# to #pscore_# - void calc_idealspacing(); -}; -#endif diff --git a/hdr/scoreline.hh b/hdr/scoreline.hh deleted file mode 100644 index f4e1987033..0000000000 --- a/hdr/scoreline.hh +++ /dev/null @@ -1,33 +0,0 @@ -/* - scoreline.hh -- part of LilyPond - - (c) 1996,97 Han-Wen Nienhuys -*/ - -#ifndef SCORELINE_HH -#define SCORELINE_HH -#include "proto.hh" -#include "plist.hh" -#include "varray.hh" - -/// the columns of a score that form one line. -struct -Line_of_score { - PointerList cols; - - // need to store height of each staff. - IPointerList staffs; - PScore * pscore_l_; // needed to generate staffs - - /* *************** */ - void process() ; - Line_of_score(Array sv, PScore *); - - String TeXstring() const; - - // is #c# contained in #*this#? - bool element(const PCol *c); -}; - -#endif - diff --git a/hdr/script-def.hh b/hdr/script-def.hh deleted file mode 100644 index 8b5be32561..0000000000 --- a/hdr/script-def.hh +++ /dev/null @@ -1,25 +0,0 @@ -/* - script-def.hh -- part of LilyPond - - (c) 1996,97 Han-Wen Nienhuys -*/ - -#ifndef SCRIPTDEF_HH -#define SCRIPTDEF_HH -#include "string.hh" -struct Script_def{ - int stemdir; - int staffdir; - - bool invertsym; - String symidx; - - /* *************** */ - int compare(Script_def const &); - void print() const; - Script_def(String, int, int ,bool); -}; - - -#endif // SCRIPTDEF_HH - diff --git a/hdr/script-reg.hh b/hdr/script-reg.hh deleted file mode 100644 index 33592cae03..0000000000 --- a/hdr/script-reg.hh +++ /dev/null @@ -1,29 +0,0 @@ -/* - script-reg.hh -- part of LilyPond - - (c) 1997 Han-Wen Nienhuys -*/ - - -#ifndef SCRIPTREG_HH -#define SCRIPTREG_HH - -#include "register.hh" - - -struct Script_register : Request_register { - Script * script_p_; - Script_req * script_req_l_; - int dir_i_; - /* *************** */ - void set_feature(Features dir_i_); - Script_register(); - virtual bool try_request(Request*); - virtual void process_requests(); - virtual void acknowledge_element(Staff_elem_info); - virtual void pre_move_processing(); - virtual void post_move_processing(); - NAME_MEMBERS(Script_register); -}; - -#endif // SCRIPTREG_HH diff --git a/hdr/script.hh b/hdr/script.hh deleted file mode 100644 index df408f0435..0000000000 --- a/hdr/script.hh +++ /dev/null @@ -1,41 +0,0 @@ -/* - script.hh -- part of LilyPond - - (c) 1996,97 Han-Wen Nienhuys -*/ - -#ifndef SCRIPT_HH -#define SCRIPT_HH - -#include "script-def.hh" -#include "item.hh" - -struct Script : Item { - int dir; - int symdir; - int pos; - int staffsize; - Script_def *specs_l_; - Stem *stem_l_; - Array support; - - /* *************** */ - NAME_MEMBERS(Script); - Molecule *brew_molecule_p()const; - virtual void do_post_processing(); - virtual void do_pre_processing(); - Script(Script_req*, int staffsize); - void set_support(Item*); - void set_stem(Stem*); - Interval support_height()const; - virtual Interval width() const; -private: - void set_symdir(); - void set_default_dir(); - void set_default_index(); - Symbol symbol()const; -}; - - -#endif // SCRIPT_HH - diff --git a/hdr/slur-reg.hh b/hdr/slur-reg.hh deleted file mode 100644 index e357c8795e..0000000000 --- a/hdr/slur-reg.hh +++ /dev/null @@ -1,33 +0,0 @@ -/* - slur-reg.hh -- declare Slur_register - - (c) 1997 Han-Wen Nienhuys -*/ - - -#ifndef SLURREG_HH -#define SLURREG_HH - -#include "register.hh" - -struct Slur_register : Request_register { - Array requests_arr_; - Array new_slur_req_l_arr_; - Array slur_l_stack_; - Array end_slur_l_arr_; - - int dir_i_; - - /* *************** */ - ~Slur_register(); - Slur_register(); - virtual bool try_request(Request*); - virtual void process_requests(); - virtual void acknowledge_element(Staff_elem_info); - virtual void pre_move_processing(); - virtual void post_move_processing(); - virtual void set_feature(Features); - NAME_MEMBERS(Slur_register); -}; - -#endif // SLURREG_HH diff --git a/hdr/slur.hh b/hdr/slur.hh deleted file mode 100644 index 87f1fe855e..0000000000 --- a/hdr/slur.hh +++ /dev/null @@ -1,37 +0,0 @@ -/* - slur.hh -- part of LilyPond - - (c) 1996,97 Han-Wen Nienhuys -*/ - -#ifndef SLUR_HH -#define SLUR_HH - -#include "directional-spanner.hh" -#include "fproto.hh" -#include "varray.hh" - -struct Slur : Directional_spanner { - - Array encompass; - - bool open_left, open_right; - - /* *************** */ - Offset center() const; - Slur(); - void do_post_processing(); - void do_pre_processing(); - void add(Notehead*); - void set_default_dir(); - - Spanner* do_break_at( PCol*, PCol*) const; - void process(); -private: - Molecule*brew_molecule_p()const; - NAME_MEMBERS(Slur); -}; - -#endif // SLUR_HH - - diff --git a/hdr/spanner.hh b/hdr/spanner.hh deleted file mode 100644 index 43a3567fa5..0000000000 --- a/hdr/spanner.hh +++ /dev/null @@ -1,54 +0,0 @@ -/* - spanner.hh -- part of LilyPond - - (c) 1996,97 Han-Wen Nienhuys -*/ - -#ifndef SPANNER_HH -#define SPANNER_HH - -#include "proto.hh" -#include "staff-elem.hh" - - -/** a symbol which is attached between two columns. A spanner is a symbol which spans across several columns, so its - final appearance can only be calculated after the breaking problem - is solved. - - Examples - - - (de)crescendo - - slur - - beam - - bracket - - - Spanner should know about the items which it should consider: - e.g. slurs should be steep enough to "enclose" all those items. This - is absolutely necessary for beams, since they have to adjust the - length of stems of notes they encompass. - - */ -struct Spanner:Staff_elem { - PCol *left, *right; - - - /* *************** */ - - Spanner(); - virtual Interval width()const; - void do_print()const; - - Spanner *broken_at(PCol *c1, PCol *c2) const; - virtual Spanner* spanner() { return this; } -protected: - - /** - clone a piece of this spanner. - PRE - c1 >= start, c2 <= stop - */ - virtual Spanner *do_break_at( PCol *c1, PCol *c2) const=0; - NAME_MEMBERS(Spanner); -}; -#endif diff --git a/hdr/staff-column.hh b/hdr/staff-column.hh deleted file mode 100644 index dd6303ea8c..0000000000 --- a/hdr/staff-column.hh +++ /dev/null @@ -1,48 +0,0 @@ -/* - staff-column.hh -- declare Staff_column - - (c) 1996,97 Han-Wen Nienhuys -*/ - -#ifndef STAFFCOLUMN_HH -#define STAFFCOLUMN_HH -#include "proto.hh" -#include "varray.hh" -#include "moment.hh" - -/// store simultaneous requests -class Staff_column { - - Staff_column(Staff_column const&); - -public: - Array creationreq_l_arr_; - Array musicalreq_l_arr_; - Array commandreq_l_arr_; - Staff * staff_l_; - - /// fields to collect timing data vertically. - Array timing_req_l_arr_; - Score_column *musical_column_l_, *command_column_l_; - - /* *************** */ - - Staff_column(); - - Moment when() const; - void set_cols(Score_column *c1, Score_column *c2); - void add(Voice_element*ve); - void OK() const; - ~Staff_column(); - void typeset_breakable_items(Array &pre_p_arr, - Array &nobreak_p_arr, - Array &post_p_arr); - void typeset_musical_item(Item *i); -protected: - void setup_one_request(Request*); -}; - - - -#endif // STAFFCOLUMN_HH - diff --git a/hdr/staff-elem-info.hh b/hdr/staff-elem-info.hh deleted file mode 100644 index 9c6264a86b..0000000000 --- a/hdr/staff-elem-info.hh +++ /dev/null @@ -1,43 +0,0 @@ -/* - staff-elem-info.hh -- declare Staff_elem_info - - source file of the LilyPond music typesetter - - (c) 1997 Han-Wen Nienhuys -*/ - - -#ifndef STAFFELEMINFO_HH -#define STAFFELEMINFO_HH - -#include "proto.hh" -#include "varray.hh" -/// data container. -struct Staff_elem_info { - Staff_elem * elem_p_; - Request*req_l_; - const Voice * voice_l_; - Array origin_reg_l_arr_; - - - /* *** */ - Staff_elem_info(Staff_elem*, Request*); - Staff_elem_info(); -}; - -struct Staff_info { - int *c0_position_i_; - Staff_walker *walk_l_; - const Time_description *time_c_l_; - const Rhythmic_grouping *rhythmic_c_l_; -}; - - -struct Features { - bool initialiser_b_; - int direction_i_; - - Features(); - static Features dir(int); -}; -#endif // STAFFELEMINFO_HH diff --git a/hdr/staff-elem.hh b/hdr/staff-elem.hh deleted file mode 100644 index e2fce84582..0000000000 --- a/hdr/staff-elem.hh +++ /dev/null @@ -1,88 +0,0 @@ -/* - staff-elem.hh -- part of LilyPond - - (c) 1996,97 Han-Wen Nienhuys -*/ - -#ifndef STAFFELEM_HH -#define STAFFELEM_HH -#include "varray.hh" -#include "proto.hh" -#include "offset.hh" -#include "molecule.hh" -#include "class-name.hh" - - -/** Both Spanner and Item are Staff_elem's. Most Staff_elem's depend - on other Staff_elem's, eg, Beam needs to know and set direction of - Stem. So the Beam has to be calculated *before* Stem. This is - accomplished with the dependencies field of struct Staff_elem. - - */ -struct Staff_elem { - enum Status { - ORPHAN, // not yet added to pstaff - VIRGIN, // added to pstaff - PRECALCING, - PRECALCED, // calcs before spacing done - POSTCALCING, - POSTCALCED, // after spacing calcs done - OUTPUT, // molecule has been output - } status; - - /// the pstaff it is in - PStaff *pstaff_l_; - - /* *************** */ - Staff_elem(Staff_elem const&); - String TeXstring () const ; - virtual void print() const; - virtual Interval width() const; - virtual Interval height() const; - Paper_def *paper() const; - virtual ~Staff_elem(); - Staff_elem(); - NAME_MEMBERS(Staff_elem); - void translate(Offset); - void add_processing(); - void pre_processing(); - void post_processing(); - void molecule_processing(); - - virtual Spanner* spanner() { return 0; } - virtual Item * item() { return 0; } - void add_dependency(Staff_elem* ); - void substitute_dependency(Staff_elem* old, Staff_elem * newdep); - -protected: - - /// do printing of derived info. - virtual void do_print() const=0; - /// generate the molecule - virtual Molecule* brew_molecule_p()const=0; - ///executed directly after the item is added to the PScore - virtual void do_add_processing(); - /// do calculations before determining horizontal spacing - virtual void do_pre_processing(); - - /// do calculations after determining horizontal spacing - virtual void do_post_processing(); - - Array dependants; - -private: - /// member: the symbols - Molecule *output; // should scrap, and use temp var? - - - /** - This is needed, because #output# may still be - NULL. - */ - Offset offset_; - Array dependencies; -}; - - -#endif // STAFFELEM_HH - diff --git a/hdr/staff-walker.hh b/hdr/staff-walker.hh deleted file mode 100644 index fb0d098e07..0000000000 --- a/hdr/staff-walker.hh +++ /dev/null @@ -1,47 +0,0 @@ -/* - staff-walker.hh -- declare Staff_walker - - (c) 1996,97 Han-Wen Nienhuys -*/ - -#ifndef STAFFWALKER_HH -#define STAFFWALKER_HH - -#include "proto.hh" -#include "time-description.hh" -#include "pcursor.hh" - -/** - manage run-time info when walking staffcolumns such as: key, - meter, pending beams & slurs - */ -struct Staff_walker : public PCursor { - Staff * staff_l_; - PScore * pscore_l_; - Score_walker *score_walk_l_; - Time_description time_; - Rhythmic_grouping *default_grouping; - - /* *************** */ - - Moment when() const; - virtual ~Staff_walker(); - Staff_walker(Staff*, PScore*); - void process() ; - - void operator++(int); - void allow_break(); - -protected: - /// every time before ++ is called - virtual void do_pre_move(){} - /// every time after ++ is called - virtual void do_post_move(){} - virtual void process_requests()=0; -private: - void process_timing_reqs(); - Staff_walker(Staff_walker const&); -}; - -#endif // STAFFWALKER_HH - diff --git a/hdr/staff.hh b/hdr/staff.hh deleted file mode 100644 index 959859b6e4..0000000000 --- a/hdr/staff.hh +++ /dev/null @@ -1,61 +0,0 @@ -/* - staff.hh -- declare Staff - - source file of the LilyPond music typesetter - - (c) 1997 Han-Wen Nienhuys -*/ - -#ifndef STAFF_HH -#define STAFF_HH - -#include "plist.hh" -#include "proto.hh" -#include "moment.hh" - -/// base class for a collection of voices. -class Staff { - Staff(const Staff&src); - - /// synchronous horizontal stuff - IPointerList voice_list_; - Staff_column *get_col(Moment, PCursor * last= 0); - -public: - - /// runtime field - IPointerList cols_; - - Score *score_l_; - PScore *pscore_l_; - PStaff *pstaff_l_; - - /* *************************************************************** */ - - void add(const PointerList &s); - - void add_voice(Voice *v); - Paper_def*paper()const; - - void setup_staffcols(); - - void OK() const; - void print() const; - - /// when does the last *musical* element finish? - Moment last() const; - -// /// extract midi info -// Midi_track* midi_track_p(); - - /// remove unused cols - void clean_cols() ; - Staff(); - - virtual void set_output(PScore * destination)=0; - virtual Staff_walker *get_walker_p()=0; - virtual ~Staff() { } -protected: - -}; -#endif diff --git a/hdr/staffline.hh b/hdr/staffline.hh deleted file mode 100644 index 9fbe3ec917..0000000000 --- a/hdr/staffline.hh +++ /dev/null @@ -1,31 +0,0 @@ -/* - staffline.hh -- horizontal structures for broken scores. - - (c) 1996,97 Han-Wen Nienhuys -*/ - -#ifndef STAFFLINE_HH -#define STAFFLINE_HH - -#include "proto.hh" -#include "real.hh" -#include "plist.hh" -#include "varray.hh" -#include "glob.hh" -#include "pstaff.hh" - -/// one broken line of staff. -struct Line_of_staff { - - Line_of_score * line_of_score_l_; - PStaff *pstaff_l_; - - /* *************** */ - - String TeXstring() const; - Line_of_staff(Line_of_score*, PStaff *); - Interval height() const; - void process(); -}; - -#endif diff --git a/hdr/staffsym.hh b/hdr/staffsym.hh deleted file mode 100644 index bcec2bfaff..0000000000 --- a/hdr/staffsym.hh +++ /dev/null @@ -1,30 +0,0 @@ -/* - staffsym.hh -- declare Staff_symbol - - source file of the LilyPond music typesetter - - (c) 1997 Han-Wen Nienhuys -*/ - - -#ifndef STAFFSYM_HH -#define STAFFSYM_HH -#include "spanner.hh" -/** - This spanner draws the lines of a pstaff. - The bottom line is position 0. - */ -class Staff_symbol : public Spanner -{ -public: - /// this many lines. - int no_lines_i_; - - NAME_MEMBERS(Staff_symbol); - Staff_symbol(int lines); - virtual Molecule* brew_molecule_p() const; - void set_extent(PCol* p1, PCol* p2); - virtual void do_print()const; - virtual Spanner *do_break_at( PCol *c1, PCol *c2) const; -}; -#endif // STAFFSYM_HH diff --git a/hdr/stem-beam-reg.hh b/hdr/stem-beam-reg.hh deleted file mode 100644 index dddba269a4..0000000000 --- a/hdr/stem-beam-reg.hh +++ /dev/null @@ -1,33 +0,0 @@ -/* - stem-beam-reg.hh -- part of LilyPond - - (c) 1997 Han-Wen Nienhuys -*/ - - -#ifndef STEMBEAMREG_HH -#define STEMBEAMREG_HH -#include "register.hh" - -struct Stem_beam_register : Request_register { - Stem * stem_p_; - Beam * beam_p_; - Beam_req * beam_req_l_; - Stem_req * stem_req_l_; - Beam_req * start_req_l_; - bool end_beam_b_; - Rhythmic_grouping *current_grouping; - int default_dir_i_; - - /* *************** */ - Stem_beam_register(); - ~Stem_beam_register(); - virtual void set_feature(Features dir_i_); - virtual bool try_request(Request*); - virtual void process_requests(); - virtual void acknowledge_element(Staff_elem_info); - virtual void pre_move_processing(); - virtual void post_move_processing(); - NAME_MEMBERS(Stem_beam_register); -}; -#endif // STEMBEAMREG_HH diff --git a/hdr/stem.hh b/hdr/stem.hh deleted file mode 100644 index 34776ea49c..0000000000 --- a/hdr/stem.hh +++ /dev/null @@ -1,81 +0,0 @@ -/* - stem.hh -- declare Stem - - (c) 1996,97 Han-Wen Nienhuys -*/ - -#ifndef STEM_HH -#define STEM_HH -#include "item.hh" -#include "varray.hh" -#include "moment.hh" - - -/**the rule attached to the ball. - takes care of: - - \begin{itemize} - \item the rule - \item the flag - \item up/down position. - \end{itemize} - */ - -struct Stem : Item { - /// heads that the stem encompasses (positions) - int minnote, maxnote; - - /// false if in beam - bool print_flag; - - int beams_left; - int beams_right; - - /// needed for determining direction/length - int staff_center; - - - /**extent of the stem (positions). - fractional, since Beam has to adapt them. - */ - - Real bot, top; - Real stemlen; - - /// flagtype? 4 none, 8 8th flag, 0 = beam. - int flag; - - - /** - geen gedonder, jij gaat onder. - -1 stem points down, +1: stem points up - */ - - int dir; - Real stem_xoffset; - - Array heads; - - /* *************** */ - Stem(int center); //, Moment duration); - - /// ensure that this Stem also encompasses the Notehead #n# - void add(Notehead*n); - - NAME_MEMBERS(Stem); - - Real hindex()const; - void do_print() const; - void set_stemend(Real); - int get_default_dir(); - void set_default_dir(); - void set_default_stemlen(); - void set_default_extents(); - void set_noteheads(); - void do_pre_processing(); - - Interval width() const; - - Molecule* brew_molecule_p() const; -}; -#endif diff --git a/hdr/symbol.hh b/hdr/symbol.hh deleted file mode 100644 index c166fa5bcf..0000000000 --- a/hdr/symbol.hh +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef SYMBOL_HH -#define SYMBOL_HH - -#include "string.hh" -#include "boxes.hh" -#include "proto.hh" - -struct Symbol { - String tex; - Box dim; - - Symbol (String, Box); - Symbol(); - String str()const; // for printing. -}; - -#endif diff --git a/hdr/symtable.hh b/hdr/symtable.hh deleted file mode 100644 index f96d02c1ec..0000000000 --- a/hdr/symtable.hh +++ /dev/null @@ -1,28 +0,0 @@ -/* - lilypond, (c) 1996,97 Han-Wen Nienhuys -*/ -#ifndef SYMTABLE_HH -#define SYMTABLE_HH -#include "assoc.hh" -#include "string.hh" -#include "symbol.hh" - -struct Symtable : public Assoc { - Symbol lookup(String)const; - void print()const; -}; - - -struct Symtables : private Assoc { - - Symtable* operator()(String s); - ~Symtables(); - Symtables(); - Symtables(Symtables const&); - Assoc::add; - void print()const; -}; - - -#endif - diff --git a/hdr/tex-stream.hh b/hdr/tex-stream.hh deleted file mode 100644 index 4d5805c556..0000000000 --- a/hdr/tex-stream.hh +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef TSTREAM__HH -#define TSTREAM__HH - -#include -#include "string.hh" - - -/** TeX output. - Use this class for writing to a TeX file. - It counts braces to prevent nesting errors, and - it will add a comment sign before each newline. - */ -struct Tex_stream { - bool outputting_comment; - ostream *os; - int nest_level; - - /// open a file for writing - Tex_stream(String filename); - void header(); - /// delegate conversion to string class. - Tex_stream &operator<<(String); - - /// close the file - ~Tex_stream(); -private: - Tex_stream(Tex_stream const&); -}; -#endif diff --git a/hdr/tex.hh b/hdr/tex.hh deleted file mode 100644 index af45ba7d27..0000000000 --- a/hdr/tex.hh +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef TEX_HH -#define TEX_HH - -#include "string.hh" -#include "boxes.hh" -#include "scalar.hh" - -/** parameter substitution in TeXstrings. - this function provides a simple macro mechanism: - - if source == "tex%bla%", then - substitute_args(source, {"X","Y"}) == "texXblaY" - */ -String -substitute_args(String source, Array args); - -/// parameter substitution in TeXstrings -String -substitute_args(String source, Array args); - -/// #h# is in points -String vstrut(Real h); - - -#endif diff --git a/hdr/text-def.hh b/hdr/text-def.hh deleted file mode 100644 index cc9c3c95b3..0000000000 --- a/hdr/text-def.hh +++ /dev/null @@ -1,29 +0,0 @@ -/* - text-def.hh -- part of LilyPond - - (c) 1996,97 Han-Wen Nienhuys -*/ - -#ifndef TEXTDEF_HH -#define TEXTDEF_HH - -#include "string.hh" -#include "proto.hh" - -struct Text_def { - int align_i_; - String text_str_; - String style_str_; - char const* defined_ch_c_l_; - - - /* ****************/ - virtual ~Text_def() {}; - bool compare(const Text_def&); - Text_def(); - virtual void print() const; - virtual Atom create_atom(Paper_def*) const; -}; - -#endif // TEXTDEF_HH - diff --git a/hdr/text-reg.hh b/hdr/text-reg.hh deleted file mode 100644 index 59317e5bcd..0000000000 --- a/hdr/text-reg.hh +++ /dev/null @@ -1,26 +0,0 @@ -/* - text-reg.hh -- part of LilyPond - - (c) 1997 Han-Wen Nienhuys -*/ - - -#ifndef TEXTREG_HH -#define TEXTREG_HH -#include "register.hh" - -struct Text_register : Request_register{ - Text_item * text_p_; - Text_req * text_req_l_; - int dir_i_; - /* *************** */ - virtual void set_feature(Features ); - Text_register(); - virtual bool try_request(Request*); - virtual void process_requests(); - virtual void pre_move_processing(); - virtual void post_move_processing(); - NAME_MEMBERS(Text_register); -}; - -#endif // TEXTREG_HH diff --git a/hdr/textitem.hh b/hdr/textitem.hh deleted file mode 100644 index ae0b556308..0000000000 --- a/hdr/textitem.hh +++ /dev/null @@ -1,30 +0,0 @@ -/* - text.hh -- part of LilyPond - - (c) 1996,97 Han-Wen Nienhuys -*/ - -#ifndef TEXT_ITEM_HH -#define TEXT_ITEM_HH - -#include "text-def.hh" -#include "item.hh" - -struct Text_item : Item { - int pos_i_; - int staffsize_i_; - int dir_i_; - Text_def* tdef_l_; - - /* ***************/ - NAME_MEMBERS(Text_item); - virtual void set_default_index(); - Molecule* brew_molecule_p() const; - void do_pre_processing(); - - Text_item(Text_req*,int); -}; - - -#endif // TEXT_HH - diff --git a/hdr/textspanner.hh b/hdr/textspanner.hh deleted file mode 100644 index dbdea979ad..0000000000 --- a/hdr/textspanner.hh +++ /dev/null @@ -1,34 +0,0 @@ -/* - textspanner.hh -- part of LilyPond - - (c) 1996,97 Han-Wen Nienhuys -*/ - -#ifndef TEXTSPANNER_HH -#define TEXTSPANNER_HH - -#include "string.hh" -#include "directional-spanner.hh" -#include "text-def.hh" - -/** a spanner which puts texts on top of other spanners. Use for - triplets, eentweetjes, ottava, etc. */ -struct Text_spanner : Spanner { - Text_def spec; - Offset text_off_; - Directional_spanner*support; - - /* *************** */ - - NAME_MEMBERS(Text_spanner); - virtual void do_pre_processing(); - virtual void do_post_processing(); - virtual Interval height() const ; - virtual Molecule* brew_molecule_p()const; - virtual void do_print() const; - virtual Spanner* do_break_at(PCol*,PCol*)const; - Text_spanner(); - void set_support(Directional_spanner*); -}; -#endif // TEXTSPANNER_HH - diff --git a/hdr/time-description.hh b/hdr/time-description.hh deleted file mode 100644 index 7e366ec4c2..0000000000 --- a/hdr/time-description.hh +++ /dev/null @@ -1,50 +0,0 @@ -/* - moment.hh -- part of LilyPond - - (c) 1996,97 Han-Wen Nienhuys -*/ - -#ifndef tdes_HH -#define tdes_HH - -#include "moment.hh" - -/// full info on where we are -struct Time_description { - Moment when_; - - /// if true, no bars needed, no reduction of whole_in_measure - bool cadenza_b_; - - /// current measure info - Moment whole_per_measure_; - - /// where am i - Moment whole_in_measure_; - - /// how long is one beat? - Moment one_beat_; - - /// idem - int bars_i_; - - /* *************** */ - void set_cadenza(bool); - void OK() const; - Time_description(); - void add(Moment dt); - String str()const; - void print() const; - void setpartial(Moment p); - Moment barleft(); - void set_meter(int,int); - static int compare (Time_description&, Time_description&); -}; - -#include "compare.hh" - - -instantiate_compare(Time_description&,Time_description::compare); - -#endif // Time_description_HH - diff --git a/hdr/track-column.hh b/hdr/track-column.hh deleted file mode 100644 index 1d86755a9f..0000000000 --- a/hdr/track-column.hh +++ /dev/null @@ -1,24 +0,0 @@ -// -// track-column.hh -- declare Track_column -// -// copyright 1997 Jan Nieuwenhuizen - -#ifndef TRACK_COLUMN_HH -#define TRACK_COLUMN_HH - -/// (tcol) -class Track_column { -public: - Track_column( Moment mom ); - ~Track_column(); - - void add_event( Midi_event* midi_event_p ); - Moment mom(); - -//private: - IPointerList midi_event_p_list_; - Moment mom_; -}; - -#endif // TRACK_COLUMN_HH - diff --git a/hdr/voice-element.hh b/hdr/voice-element.hh deleted file mode 100644 index 0c5b6b1328..0000000000 --- a/hdr/voice-element.hh +++ /dev/null @@ -1,37 +0,0 @@ -/* - voice-element.hh -- declare Voice_element - - source file of the LilyPond music typesetter - - (c) 1997 Han-Wen Nienhuys -*/ - - -#ifndef VOICE_ELEMENT_HH -#define VOICE_ELEMENT_HH - -#include "proto.hh" -#include "plist.hh" -#include "moment.hh" - -/** one horizontal bit. Voice_element is nothing but a container for - *the requests, */ -struct Voice_element { - Moment duration; - char const* defined_ch_c_l_; - const Voice *voice_l_; - IPointerList reqs; - - /* *************** */ - - Voice_element(); - Voice_element(Voice_element const & src ); - - void add(Request*); - bool find_plet_start_bo(char c, Moment& moment_r); - void print ()const; - void set_default_group(String id); - void set_plet_backwards(Moment& now_moment_r, Moment until_moment, int num_i, int den_i); -}; - -#endif // VOICE-ELEMENT_HH diff --git a/hdr/voice-group-regs.hh b/hdr/voice-group-regs.hh deleted file mode 100644 index 7c1b4ed78a..0000000000 --- a/hdr/voice-group-regs.hh +++ /dev/null @@ -1,29 +0,0 @@ -/* - voice-group-regs.hh -- declare Voice_group_registers - - source file of the LilyPond music typesetter - - (c) 1997 Han-Wen Nienhuys -*/ - - -#ifndef VOICEGROUPREGS_HH -#define VOICEGROUPREGS_HH - -#include "registergroup.hh" - -struct Voice_group_registers : Register_group_register { - String group_id_str_; - Array voice_regs_l_; - - /* *************** */ - - NAME_MEMBERS(Voice_group_registers); - static bool static_acceptable_request_b(Request*); - virtual void terminate_register(Request_register*); - virtual void do_print() const; - virtual void add(Request_register*); - Voice_group_registers(String id); - virtual bool try_request(Request*); -}; -#endif // VOICEGROUPREGS_HH diff --git a/hdr/voice-regs.hh b/hdr/voice-regs.hh deleted file mode 100644 index 82070a704e..0000000000 --- a/hdr/voice-regs.hh +++ /dev/null @@ -1,31 +0,0 @@ -/* - voice-regs.hh -- declare Voice_registers - - source file of the LilyPond music typesetter - - (c) 1997 Han-Wen Nienhuys -*/ - - -#ifndef VOICEREGS_HH -#define VOICEREGS_HH - -#include "registergroup.hh" - -class Voice_registers : public Register_group_register { - - -public: - Voice *voice_l_; - /* *************** */ - - NAME_MEMBERS(Voice_registers); - virtual bool acceptable_request_b(Request*); - virtual void acknowledge_element(Staff_elem_info info); - virtual bool try_request(Request*); - Voice_registers(Voice*); - virtual void do_print() const; -}; - - -#endif // VOICEREGS_HH diff --git a/hdr/voice.hh b/hdr/voice.hh deleted file mode 100644 index 06e6e1da27..0000000000 --- a/hdr/voice.hh +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef VOICE_HH -#define VOICE_HH - -#include "proto.hh" -#include "plist.hh" -#include "moment.hh" - -/** class for horizontal stuff. - - Voice is a ordered row of Voice_elements. It is strictly - horizontal: you cannot have two rhythmic elements running parallel - in a Voice. For proper processing, each Voice should have - Group_change_req as a first element. - - */ - -struct Voice { - IPointerList elts; - Moment start; - - /* *************** */ - Voice(); - Voice(Voice const&); - - Moment when(const Voice_element*)const; - Moment last() const; - - void add(Voice_element*); - bool find_plet_start_bo(char c, Moment& moment_r); - void print() const; - void set_default_group(String id); - void set_plet_backwards(Moment& now_moment_r, Moment until_moment, int num_i, int den_i); -}; - -#endif diff --git a/hdr/walkregs.hh b/hdr/walkregs.hh deleted file mode 100644 index 643ce57605..0000000000 --- a/hdr/walkregs.hh +++ /dev/null @@ -1,50 +0,0 @@ -/* - walkregs.hh -- declare Walker_registers - - source file of the LilyPond music typesetter - - (c) 1997 Han-Wen Nienhuys -*/ - - -#ifndef WALKREGS_HH -#define WALKREGS_HH - - -#include "registergroup.hh" - -/** - Top level registers: the interface to Complex_walker. - - [sigh. Sometimes I wish C++ could do better late binding.] - */ -struct Walker_registers : Register_group_register { - Array prebreak_item_p_arr_; - Array nobreak_item_p_arr_; - Array postbreak_item_p_arr_; - Array announce_info_arr_; - Array group_l_arr_; - Complex_walker * walk_l_; - - /* *************** */ - void change_group(Group_change_req * greq_l, - Voice_registers *voice_regs_l, - Voice_group_registers * old_group); - Voice_group_registers * get_group(String id); - void typeset_musical_item(Staff_elem * elem_p); - Walker_registers(Complex_walker*); - void do_announces(); - void terminate_register(Request_register * reg); - virtual bool try_request(Request * r); - virtual Staff_info get_staff_info(); - - virtual void announce_element(Staff_elem_info); - virtual void acknowledge_element(Staff_elem_info); - virtual void typeset_breakable_item(Item * pre_p , Item * nobreak_p, Item * post_p); - virtual void typeset_element(Staff_elem*elem_p); - virtual void pre_move_processing(); - virtual void post_move_processing(); - virtual Paper_def * paper() const; -}; - -#endif // WALKREGS_HH diff --git a/init/Makefile b/init/Makefile index 83a2e5b9ae..ff8dd8efad 100644 --- a/init/Makefile +++ b/init/Makefile @@ -1,8 +1,20 @@ -DFILES=dutch.ini table_sixteen.ini table_twenty.ini\ - english.ini script.ini symbol.ini bare.ini swedish.ini +# init/Makefile -default: - echo huh? +# subdir level: +# +depth = .. +# + +build = ./$(depth)/lily/.build + +# generic stuff/Makefile +# +include ./$(depth)/make/Stuff.make +# + +# list of distribution files: +# +INIFILES = $(shell ls *.ini) +DISTFILES = Makefile $(INIFILES) +# -dist: - ln Makefile $(DFILES) $(DDIR)/$(INITDIR) diff --git a/init/symbol.ini b/init/symbol.ini index 82029a9e1b..7de1e0f521 100644 --- a/init/symbol.ini +++ b/init/symbol.ini @@ -1,7 +1,7 @@ include "dutch.ini" # do not include init/ path -include "script.ini" -include "table_sixteen.ini" # not needed if doing MIDI +include "script.ini" +include "table_sixteen.ini" diff --git a/input/Makefile b/input/Makefile index 47e58f972d..618e1ec24a 100644 --- a/input/Makefile +++ b/input/Makefile @@ -1,15 +1,21 @@ -default: ; +# input/Makefile -DISTFILES=Makefile kortjakje.ly maartje.ly\ - cadenza.ly scales.ly standchen.ly twinkle.ly\ - wohltemperirt.ly\ - error.ly midi.ly plet.ly\ - martien.ly mlalt.ly mlvio1.ly mlvio2.ly mlcello.ly\ - coriolan-alto.ly rhythm.ly \ - standchen.tex scsii-menuetto.tex scsii-menuetto.ly\ - martien.tex\ - pre1.midi.ly fugue1.midi.ly +# subdir level: +# +depth = .. +# +build = ./$(depth)/lily/.build + +# generic stuff/Makefile +# +include ./$(depth)/make/Stuff.make +# + +# list of distribution files: +# +LYFILES = $(shell ls *.ly) +TEXFILES = $(shell ls *.tex) +DISTFILES = Makefile $(LYFILES) $(TEXFILES) +# -dist: - ln $(DISTFILES) $(DDIR)/$(SUBDIR) diff --git a/input/midi.ly b/input/midi.ly index 9e45033808..38e5073778 100644 --- a/input/midi.ly +++ b/input/midi.ly @@ -4,7 +4,7 @@ melodie = music { $\clef\violin c c | g g | a a | g2 - f f | e e | d d8. e16 | c2 | % :| + f f | e e | d d8.( e16 | )c2 | % :| $ } @@ -33,7 +33,6 @@ score { commands { meter { 2 * 4} } - paper{} midi { tempo 4:120 } diff --git a/input/scales.ly b/input/scales.ly index 11568c9ea6..d98c1bba43 100644 --- a/input/scales.ly +++ b/input/scales.ly @@ -4,15 +4,15 @@ staff {melodic music{ $ \duration { 8 } \octave{ } - |[ a a a a a a a a a ]8/9 + |[ a a a a a a a a a ] \octave{ ' } - |[ a a a a a a a a a ]8/9 + |[ a a a a a a a a a ] \octave { ` } - [ `c `g d a 'e 'b ''f '''c '''g ] 8/9 - [ '''g '''c ''f 'b 'e a d `g `c ] 8/9 + [ `c `g d a 'e 'b ''f '''c '''g ] + [ '''g '''c ''f 'b 'e a d `g `c ] \octave{ ' } - [ `c `g d a 'e 'b ''f '''c '''g ] 8/9 - [ '''g '''c ''f 'b 'e a d `g `c ] 8/9 + [ `c `g d a 'e 'b ''f '''c '''g ] + [ '''g '''c ''f 'b 'e a d `g `c ] \octave { } [ c g 'd ]2/3 [ 'd g c ]2/3 @@ -54,7 +54,7 @@ score { } commands { meter {6*8} - skip {36*8} + skip 36*8 meter {4*4} } } diff --git a/lib/Makefile b/lib/Makefile new file mode 100644 index 0000000000..7da9879256 --- /dev/null +++ b/lib/Makefile @@ -0,0 +1,91 @@ +# +# project LilyPond -- the musical typesetter +# title makefile for micro-lily-lib +# file lib/Makefile +# +# Copyright (c) 1997 by +# Jan Nieuwenhuizen +# Han-Wen Nienhuys +# + +# subdir level: +# +depth = .. +# + +# identify module: +# +NAME = lily +MAJOR_VERSION = $(TOPLEVEL_MAJOR_VERSION) +MINOR_VERSION = $(TOPLEVEL_MINOR_VERSION) +PATCH_LEVEL = $(TOPLEVEL_PATCH_LEVEL) +# use to send patches, always empty for released version: +MY_PATCH_LEVEL = $(TOPLEVEL_MY_PATCH_LEVEL) +build = ./$(depth)/lily/.build +# + +# generic variables: +# +include ./$(depth)/make/Variables.make +# + +# descent order into subdirectories: +# +SUBDIRS = include +# + +# to be remade each build: +# +VERSION_DEPENDENCY = $(lily-version) +# + +# list of c++ header files: +# +HHFILES = # $(shell ls include/*.hh) +# + +# list of c++ source files: +# +CCFILES = $(shell ls *.cc) +# + +# list of other source files: +# +EXTRA_SOURCE_FILES = # $(shell ls *.y *.l) +# + +# list of distribution files: +# +DISTFILES = Makefile $(HHFILES) $(CCFILES) $(EXTRA_SOURCE_FILES) +# + +# list of custom libraries: +# +# yes, i know about the -L and -l options, +# but these libraries get rebuild when needed. +CUSTOMLIBES = \ + +LOADLIBES += +# + +# main target of this module: +# +# MAINTARGET = $(EXECUTABLE) +# MAINTARGET = $(LIBRARY) +# MAINTARGET = $(bindir)/$(EXECUTABLE)# huh? +MAINTARGET = $(libdir)/$(LIBRARY)# huh? + +default: $(MAINTARGET) +# + +# generic targets and rules: +# +include ./$(depth)/make/Targets.make +include ./$(depth)/make/Rules.make +# + +# auto dependencies: +# +-include ./$(outdir)/*.dep +# + diff --git a/lib/include/Makefile b/lib/include/Makefile new file mode 100644 index 0000000000..cb4f4ea6d1 --- /dev/null +++ b/lib/include/Makefile @@ -0,0 +1,23 @@ +# lib/include/Makefile + +# subdir level: +# +depth = ../.. +# + +# identify module: +# +MODULE_NAME = lilypond +MAJOR_VERSION = $(TOPLEVEL_MAJOR_VERSION) +MINOR_VERSION = $(TOPLEVEL_MINOR_VERSION) +PATCH_LEVEL = $(TOPLEVEL_PATCH_LEVEL) +# use to send patches, always empty for released version: +MY_PATCH_LEVEL = $(TOPLEVEL_MY_PATCH_LEVEL) +build = ./$(depth)/lily/.build +# + +# generic stuff/Makefile +# +include ./$(depth)/make/Include.make +# + diff --git a/lib/include/config.hh b/lib/include/config.hh new file mode 100644 index 0000000000..ca44f294d7 --- /dev/null +++ b/lib/include/config.hh @@ -0,0 +1 @@ +#define LIBDIR "./" diff --git a/lib/include/debug.hh b/lib/include/debug.hh new file mode 100644 index 0000000000..92715dbfdc --- /dev/null +++ b/lib/include/debug.hh @@ -0,0 +1,35 @@ +#ifndef DEBUG_HH +#define DEBUG_HH + +#include +#include +#include "dstream.hh" +#include "real.hh" +#include "proto.hh" + +void message( String message_str, char const* context_ch_c_l ); +void warning( String message_str, char const* context_ch_c_l ); +void error( String message_str, char const* context_ch_c_l ); +void error(String s); // errors +void error_t(const String& s, Time_description const & t_tdes); +void error_t(String const &s, const Moment &when); +// warnings +//void warning(String s); +#define WARN warnout << "warning: "<<__FUNCTION__ << "(): " +extern ostream &warnout ; + +// progress +extern ostream *mlog; + +// debugging +extern Dstream *monitor; // monitor + +#ifdef NPRINT +#define mtor if (0) *monitor // clever hack +#else +#define mtor if (check_debug) monitor->identify_as(__PRETTY_FUNCTION__) +#endif + +extern bool check_debug; + +#endif diff --git a/lib/include/input-file.hh b/lib/include/input-file.hh new file mode 100644 index 0000000000..a01ea75076 --- /dev/null +++ b/lib/include/input-file.hh @@ -0,0 +1,28 @@ +/* + input-file.hh -- declare Input_file + + source file of the LilyPond music typesetter + + (c) 1997 Han-Wen Nienhuys +*/ + +#ifndef INPUT_FILE_HH +#define INPUT_FILE_HH +#include +#include "proto.hh" +#include "fproto.hh" +#include "varray.hh" +#include "string.hh" + +struct Input_file { + istream* is; + char const* defined_ch_c_l_; + Source_file* sourcefile_l_; + int line; + String name; + + Input_file(String); + ~Input_file(); +}; + +#endif // INPUT_FILE_HH diff --git a/lib/include/moment.hh b/lib/include/moment.hh new file mode 100644 index 0000000000..0037d94078 --- /dev/null +++ b/lib/include/moment.hh @@ -0,0 +1,14 @@ +/* + (c) 1996,97 Han-Wen Nienhuys +*/ + +#ifndef MOMENT_HH +#define MOMENT_HH + +#include "rational.hh" +class String; +typedef Rational Moment; + + +#endif // + diff --git a/lib/include/proto.hh b/lib/include/proto.hh new file mode 100644 index 0000000000..e9d3e60d38 --- /dev/null +++ b/lib/include/proto.hh @@ -0,0 +1,172 @@ +/* + proto.hh -- part of LilyPond + + (c) 1996,97 Han-Wen Nienhuys +*/ + +#ifndef PROTO_HH +#define PROTO_HH + +#include "fproto.hh" +#include "real.hh" + +/// (i64) +typedef long long Int64; + +struct Absdynamic_req; +struct Accidental; +struct Atom; +struct Bar; +struct Bar_register; +struct Barcheck_req; +struct Bar_req; +struct Beam; +struct Beam_req; +struct Box; +struct Bracket_req; +struct Cadenza_req; +struct Chord; +struct Clef_change_req; +struct Clef_register; +struct Clef_item; +struct Col_hpositions; +struct Colinfo; +struct Complex_music; +struct Complex_staff; +struct Complex_walker; +struct Cresc_req; +struct Directional_spanner; +struct Decresc_req; +struct Duration; +struct Duration_iterator; +struct Durational_req; +struct Dynamic; +struct Group_change_req; +struct Group_feature_req; +struct Idealspacing; +struct Identifier; +struct Input_file; +struct Input_music; +struct Input_score; +struct Input_staff; +struct Item; +struct Key; +struct Key_register; +struct Key_change_req; +struct Key_item; +struct Keyword; +struct Keyword_table; +struct Lily_stream; +struct Line_of_score; +struct Line_of_staff; +struct Linestaff; +struct Local_key; +struct Local_key_register; +struct Local_key_item; +struct Lookup; +struct Lyric_item; +struct Lyric_req; +struct Melodic_req; +struct Measure_grouping_req; +struct Meter_change_req; +struct Meter; +struct Meter_register; +struct Midi_def; +struct Midi_duration; +struct Midi_event; +struct Midi_header; +struct Midi_item; +struct Midi_key; +struct Midi_note; +struct Midi_output; +struct Midi_pitch; +struct Midi_staff; +struct Midi_stream; +struct Midi_tempo; +struct Midi_time; +struct Midi_track; +struct Midi_voice; +struct Midi_walker; +struct Mixed_qp; +class My_midi_lexer; +class My_midi_parser; +class Midi_event; +class Midi_score; +class Midi_track; +struct Molecule; +struct Musical_req; +struct Music_general_chord; +struct Music_voice; +struct Command_req; +struct Note_req; +struct Notehead; +struct Notehead_register; +struct Notename_tab; +struct Offset; +struct Output; +struct PCol; +struct Plet_req; +struct Plet; +struct PScore; +struct PStaff; +struct Paper_def; +struct Partial_measure_req; +struct Rational; +struct Register_group_register; +struct Request; +struct Request_register; +struct Rest; +struct Rest_req; +struct Rhythmic_grouping; +struct Rhythmic_grouping_req; +struct Rhythmic_req; +struct Score; +struct Score_column; +struct Score_walker; +struct Script_def; +struct Script; +struct Script_register; +struct Script_req; +struct Simple_music; +struct Skip_req; +struct Slur; +struct Slur_register; +struct Slur_req; +struct Source; +struct Source_file; +struct Spacing_req ; +struct Span_req; +struct Spanner; +struct Blank_req; +struct Staff; +struct Staff_column; +struct Staff_elem; +struct Staff_elem_info; +struct Staff_symbol; +struct Staff_walker; +struct Stem; +struct Stem_req; +struct Stem_beam_register; +struct String; +struct Symbol; +struct Symtable; +struct Symtables; +struct Tex_stream; +struct Terminate_voice_req; +struct Text_item ; +struct Text_def; +struct Text_gob; +struct Text_register; +struct Text_req; +struct Timing_req; +struct Time_description; +struct Track_column; +struct Voice; +struct Voice_element; +struct Voice_group_registers; +struct Voice_list; +struct Voice_registers; +struct Voicegroup; +struct Walker_registers; +typedef Rational Moment; +#endif // PROTO_HH diff --git a/lib/include/windhoos-suck-suck-suck-thank-you-cygnus.hh b/lib/include/windhoos-suck-suck-suck-thank-you-cygnus.hh new file mode 100644 index 0000000000..540be21682 --- /dev/null +++ b/lib/include/windhoos-suck-suck-suck-thank-you-cygnus.hh @@ -0,0 +1,13 @@ +// +// windhoos-suck-suck-suck-thank-you-cygnus.hh +// +#ifdef _WIN32 +#ifndef WINDHOOS_SUCK_SUCK_SUCK_HH +#define WINDHOOS_SUCK_SUCK_SUCK_HH + +caddr_t mmap(caddr_t addr, size_t len, int prot, int flags, int fd, off_t offset); + +int munmap(caddr_t addr, size_t len); + +#endif // WINDHOOS_SUCK_SUCK_SUCK_HH +#endif // _WIN32 // diff --git a/lib/source-file.cc b/lib/source-file.cc new file mode 100644 index 0000000000..a39a57cbfa --- /dev/null +++ b/lib/source-file.cc @@ -0,0 +1,214 @@ +// +// source-file.cc +// + +#include // open, mmap +#include // open +#include // mmap +#include // INT_MAX +#include // open +#include // close, stat +#include // fdopen +#include // strerror +#include // errno +#include +#include + +#include "string.hh" +#include "proto.hh" +#include "plist.hh" + +//#include "lexer.hh" + +#include "debug.hh" +#include "windhoos-suck-suck-suck-thank-you-cygnus.hh" +// #include "parseconstruct.hh" // defined_ch_c_l +extern char const* defined_ch_c_l; + +// ugh +// #include "main.hh" // find_file +String find_file(String); + +#include "source-file.hh" + +Source_file::Source_file( String &filename_str ) +{ + data_caddr_ = 0; + fildes_i_ = 0; + size_off_ = 0; + name_str_ = filename_str; + istream_p_ = 0; + + open(); + map(); + // ugh!?, should call name_str() ! + filename_str = name_str_; +} + +Source_file::~Source_file() +{ + delete istream_p_; + istream_p_ = 0; + unmap(); + close(); +} + +char const* +Source_file::ch_c_l() +{ + assert( this ); + return (char const*)data_caddr_; +} + +void +Source_file::close() +{ + if ( fildes_i_ ) { + ::close( fildes_i_ ); + fildes_i_ = 0; + } +} + +String +Source_file::error_str( char const* pos_ch_c_l ) +{ + assert( this ); + if ( !in_b( pos_ch_c_l ) ) + return ""; + + char const* begin_ch_c_l = pos_ch_c_l; + char const* data_ch_c_l = ch_c_l(); + while ( begin_ch_c_l > data_ch_c_l ) + if ( *--begin_ch_c_l == '\n' ) { + begin_ch_c_l++; + break; + } + + char const* end_ch_c_l = pos_ch_c_l; + while ( end_ch_c_l < data_ch_c_l + size_off_ ) + if ( *end_ch_c_l++ == '\n' ) { + break; + } + end_ch_c_l--; + +#if 1 +// String( char const* p, int length ) is missing!? + String line_str( (Byte const*)begin_ch_c_l, end_ch_c_l - begin_ch_c_l ); +#else + int length_i = end_ch_c_l - begin_ch_c_l; + char* ch_p = new char[ length_i + 1 ]; + strncpy( ch_p, begin_ch_c_l, length_i ); + ch_p[ length_i ] = 0; + String line_str( ch_p ); + delete ch_p; +#endif + + int error_col_i = 0; + char const* scan_ch_c_l = begin_ch_c_l; + while ( scan_ch_c_l < pos_ch_c_l ) + if ( *scan_ch_c_l++ == '\t' ) + error_col_i = ( error_col_i / 8 + 1 ) * 8; + else + error_col_i++; + + String str = line_str.left_str( pos_ch_c_l - begin_ch_c_l ) + + String( '\n' ) + + String( ' ', error_col_i ) + + line_str.mid_str( pos_ch_c_l - begin_ch_c_l, INT_MAX ); // String::mid should take 0 arg.. + return str; +} + +bool +Source_file::in_b( char const* pos_ch_c_l ) +{ + return ( pos_ch_c_l && ( pos_ch_c_l >= ch_c_l() ) && ( pos_ch_c_l < ch_c_l() + size_off_ ) ); +} + +istream* +Source_file::istream_l() +{ + assert( fildes_i_ ); + if ( !istream_p_ ) { + if ( size_off_ ) // can-t this be done without such a hack? + istream_p_ = new istrstream( ch_c_l(), size_off_ ); + else { + istream_p_ = new istrstream( "", 0 ); + istream_p_->set(ios::eofbit); + } + } + return istream_p_; +} + +off_t +Source_file::length_off() +{ + return size_off_; +} + +int +Source_file::line_i( char const* pos_ch_c_l ) +{ + if ( !in_b( pos_ch_c_l ) ) + return 0; + + int i = 1; + char const* scan_ch_c_l = ch_c_l(); + while ( scan_ch_c_l < pos_ch_c_l ) + if ( *scan_ch_c_l++ == '\n' ) + i++; + return i; +} + +void +Source_file::map() +{ + if ( fildes_i_ == -1 ) + return; + + data_caddr_ = (caddr_t)mmap( (void*)0, size_off_, PROT_READ, MAP_SHARED, fildes_i_, 0 ); + + if ( (int)data_caddr_ == -1 ) + // ugh: defined_ch_c_l... + warning( String( "can't map: " ) + name_str_ + String( ": " ) + strerror( errno ), defined_ch_c_l ); //lexer->here_ch_c_l() ); +} + +String +Source_file::name_str() +{ + return name_str_; +} + +void +Source_file::open() +{ + String name_str = find_file( name_str_ ); + if ( name_str != "" ) + name_str_ = name_str; + + fildes_i_ = ::open( name_str_, O_RDONLY ); + + if ( fildes_i_ == -1 ) { + warning( String( "can't open: " ) + name_str_ + String( ": " ) + strerror( errno ), defined_ch_c_l ); // lexer->here_ch_c_l() ); + return; + } + + struct stat file_stat; + fstat( fildes_i_, &file_stat ); + size_off_ = file_stat.st_size; +} + +void +Source_file::unmap() +{ + if ( data_caddr_ ) { + munmap( data_caddr_, size_off_ ); + data_caddr_ = 0; + size_off_ = 0; + } +} +String +Source_file::file_line_no_str(char const *ch_c_l ) +{ + return name_str() + ": " + + String( line_i( ch_c_l ) ); +} diff --git a/lib/source.cc b/lib/source.cc new file mode 100644 index 0000000000..8a8c528835 --- /dev/null +++ b/lib/source.cc @@ -0,0 +1,36 @@ +// +// source.cc +// + +#include + +#include "string.hh" +#include "proto.hh" +#include "plist.hh" + +#include "source-file.hh" +#include "source.hh" + +Source::Source() +{ +} + +Source::~Source() +{ +} + +void +Source::add( Source_file* sourcefile_p ) +{ + sourcefile_p_iplist_.bottom().add( sourcefile_p ); +} + +Source_file* +Source::sourcefile_l( char const* ch_c_l ) +{ + PCursor sourcefile_l_pcur( sourcefile_p_iplist_.top() ); + for ( ; sourcefile_l_pcur.ok(); sourcefile_l_pcur++ ) + if ( sourcefile_l_pcur->in_b( ch_c_l ) ) + return *sourcefile_l_pcur; + return 0; +} diff --git a/lib/windhoos-suck-suck-suck-thank-you-cygnus.cc b/lib/windhoos-suck-suck-suck-thank-you-cygnus.cc new file mode 100644 index 0000000000..15db908eab --- /dev/null +++ b/lib/windhoos-suck-suck-suck-thank-you-cygnus.cc @@ -0,0 +1,103 @@ +// +// windhoos.cc +// +#ifdef _WIN32 + +#include +#include +#include +#include "windhoos-suck-suck-suck-thank-you-cygnus.hh" + +/* +HANDLE CreateFileMapping( + HANDLE hFile, // handle to file to map + LPSECURITY_ATTRIBUTES lpFileMappingAttributes, // optional security attributes + DWORD flProtect, // protection for mapping object + DWORD dwMaximumSizeHigh, // high-order 32 bits of object size + DWORD dwMaximumSizeLow, // low-order 32 bits of object size + LPCTSTR lpName // name of file-mapping object + ); + + +LPVOID MapViewOfFile( + HANDLE hFileMappingObject, // file-mapping object to map into address space + DWORD dwDesiredAccess, // access mode + DWORD dwFileOffsetHigh, // high-order 32 bits of file offset + DWORD dwFileOffsetLow, // low-order 32 bits of file offset + DWORD dwNumberOfBytesToMap // number of bytes to map + ); + + +io.h: +long _get_osfhandle( int filehandle ); +*/ + +// cygnus's gnu-win32-b17.1 does not have _get_osfhandle +// however, after some hacking, it turns out that: + +static const int OSF_OFFSET_i = 72; +static const int OSF_BASE_i = -3; +static const int OSF_FACTOR_i = 8; +// let-s hope bill doesn-t change his mind any time soon :-) + +// so that, while waiting for cygnus's mmap, we can write: + +// #define HAVE_GET_OSFHANDLE // no we still cannot; works only with cl.exe +long +_get_osfhandle( int filedes_i ) +{ + return (long)( OSF_OFFSET_i + ( filedes_i + OSF_BASE_i ) * OSF_FACTOR_i ); +} + +#ifdef HAVE_GET_OSFHANDLE + +#include + +caddr_t +mmap(caddr_t addr, size_t len, int prot, int flags, int fd, off_t offset) +{ + (void)flags; + (void)prot; + (void)addr; + HANDLE osf = (HANDLE)_get_osfhandle( fd ); + HANDLE file_handle = CreateFileMapping( osf, (void*)0, PAGE_READONLY, + 0, len, 0 ); + return (caddr_t)MapViewOfFile( file_handle, FILE_MAP_READ, 0, offset, len ); +} + + +int +munmap(caddr_t addr, size_t len) +{ + (void)len; + return UnmapViewOfFile( addr ); +} + +#else // ! HAVE_GET_OSFHANDLE // + +caddr_t +mmap(caddr_t addr, size_t len, int prot, int flags, int fd, off_t offset) +{ + (void)flags; + (void)prot; + (void)addr; + (void)offset; + char* ch_p = new char[ len ]; + if ( ch_p ) + read( fd, (void*)ch_p, len ); + return ch_p; +} + + +int +munmap(caddr_t addr, size_t len) +{ + (void)len; + delete (char*)addr; + return 0; +} + +#endif // !HAVE_GET_OSFHANDLE // + + +#endif // _WIN32 // diff --git a/lily/Makefile b/lily/Makefile new file mode 100644 index 0000000000..f31a93426a --- /dev/null +++ b/lily/Makefile @@ -0,0 +1,99 @@ +# +# project LilyPond -- the musical typesetter +# title makefile for lilypond +# file lily/Makefile +# +# Copyright (c) 1997 by +# Jan Nieuwenhuizen +# Han-Wen Nienhuys +# + +# subdir level: +# +depth = .. +# + +# identify module: +# +NAME = lilypond +MAJOR_VERSION = $(TOPLEVEL_MAJOR_VERSION) +MINOR_VERSION = $(TOPLEVEL_MINOR_VERSION) +PATCH_LEVEL = $(TOPLEVEL_PATCH_LEVEL) +# use to send patches, always empty for released version: +MY_PATCH_LEVEL = $(TOPLEVEL_MY_PATCH_LEVEL) +build = ./$(depth)/lily/.build +# + +# generic variables: +# +include ./$(depth)/make/Variables.make +# + +# descent order into subdirectories: +# +SUBDIRS = include +# + +# to be remade each build: +# +VERSION_DEPENDENCY = $(lily-version) +# + +# list of c++ header files: +# +HHFILES = # $(shell ls include/*.hh) +# + +# list of c++ source files: +# +CCFILES = $(shell ls *.cc) +# + +# list of other source files: +# +EXTRA_SOURCE_FILES = $(shell ls *.y *.l) +# + +# list of distribution files: +# +DISTFILES = Makefile $(HHFILES) $(CCFILES) $(EXTRA_SOURCE_FILES) +# + +# list of custom libraries: +# +# yes, i know about the -L and -l options, +# but these libraries get rebuild when needed. +CUSTOMLIBES = $(LIBLILY) $(LIBFLOWER) + +LOADLIBES += +# + +# main target of this module: +# +# MAINTARGET = $(EXECUTABLE) +# MAINTARGET = $(LIBRARY) +MAINTARGET = $(bindir)/$(EXECUTABLE)# huh? +# MAINTARGET = $(libdir)/$(LIBRARY)# huh? + +default: $(MAINTARGET) +# + +# generic targets and rules: +# +include ./$(depth)/make/Targets.make +include ./$(depth)/make/Rules.make +# + +# explicit dependencies: (how to do auto?) +# +# ugh +$(outdir)/version.cc: check-flower-version $(lily-version) +mylexer.cc: $(outdir)/parser.hh # sic +lexer.l: $(outdir)/parser.hh +# + +# auto dependencies: +# +-include ./$(outdir)/*.dep +# + diff --git a/lily/bar-reg.cc b/lily/bar-reg.cc new file mode 100644 index 0000000000..b72eca8755 --- /dev/null +++ b/lily/bar-reg.cc @@ -0,0 +1,79 @@ +/* + bar-reg.cc -- implement Bar_register + + source file of the LilyPond music typesetter + + (c) 1997 Han-Wen Nienhuys +*/ + +#include "bar-reg.hh" +#include "bar.hh" +#include "commandrequest.hh" +#include "score-column.hh" +#include "time-description.hh" + +Bar_register::Bar_register() +{ + post_move_processing(); +} + +bool +Bar_register::try_request(Request*r_l) +{ + Command_req* c_l = r_l->command(); + if (!c_l|| !c_l->bar()) + return false; + + assert(!bar_req_l_); + bar_req_l_ = c_l->bar(); + + return true; +} + +void +Bar_register::process_requests() +{ + if (bar_req_l_ ) { + bar_p_ = new Bar(bar_req_l_->type_str_); + } else if (!get_staff_info().time_c_l_->whole_in_measure_) { + bar_p_ = new Bar("|"); + } + + if (bar_p_){ + announce_element(Staff_elem_info(bar_p_, bar_req_l_) ); + } +} + +void +Bar_register::split_bar(Bar *& pre, Bar * no, Bar * &post) +{ + String s= no->type; + if (s == ":|:") { + pre = new Bar(":|"); + post = new Bar("|:"); + }else if (s=="|:") { + post = new Bar(s); + } else { + pre = new Bar(*no); + } +} + +void +Bar_register::pre_move_processing() +{ + if (bar_p_) { + Bar * post_p =0; + Bar * pre_p =0; + split_bar(pre_p, bar_p_, post_p); + + typeset_breakable_item(pre_p, bar_p_, post_p); + bar_p_ =0; + } +} + +void +Bar_register::post_move_processing() +{ + bar_req_l_ = 0; + bar_p_ =0; +} diff --git a/lily/bar.cc b/lily/bar.cc new file mode 100644 index 0000000000..32a7cd5fe6 --- /dev/null +++ b/lily/bar.cc @@ -0,0 +1,28 @@ +#include "bar.hh" +#include "string.hh" +#include "molecule.hh" +#include "paper-def.hh" +#include "lookup.hh" +#include "debug.hh" + + + +Bar::Bar( String t) +{ + type = t; +} + +void +Bar::do_print()const +{ + mtor << type; +} + +Molecule* +Bar::brew_molecule_p()const +{ + Symbol s = paper()->lookup_p_->bar(type); + Molecule*output = new Molecule(Atom(s)); + return output; +} + diff --git a/lily/beam.cc b/lily/beam.cc new file mode 100644 index 0000000000..64f3e3cf77 --- /dev/null +++ b/lily/beam.cc @@ -0,0 +1,295 @@ +#include "varray.hh" + +#include "dimen.hh" +#include "beam.hh" +#include "misc.hh" +#include "debug.hh" +#include "symbol.hh" +#include "molecule.hh" +#include "leastsquares.hh" +#include "pcol.hh" +#include "stem.hh" +#include "paper-def.hh" +#include "lookup.hh" +#include "grouping.hh" + + + +struct Stem_info { + Real x; + Real idealy; + Real miny; + int no_beams; + + + Stem_info(){} + Stem_info(const Stem*); +}; + +Stem_info::Stem_info(const Stem*s) +{ + x = s->hindex(); + int dir = s->dir; + idealy = max(dir*s->top, dir*s->bot); + miny = max(dir*s->minnote, dir*s-> maxnote); + assert(miny <= idealy); + +} + +/* *************** */ + +Offset +Beam::center()const +{ + assert(status >= POSTCALCED); + + Real w=(paper()->note_width() + width().length())/2.0; + return Offset(w, (left_pos + w* slope)*paper()->internote()); +} + + +Beam::Beam() +{ + slope = 0; + left_pos = 0.0; +} + +void +Beam::add(Stem*s) +{ + stems.bottom().add(s); + s->add_dependency(this); + s->print_flag = false; +} + +void +Beam::set_default_dir() +{ + int dirs[2]; + dirs[0]=0; dirs[1] =0; + for (iter_top(stems,i); i.ok(); i++) { + int d = i->get_default_dir(); + dirs[(d+1)/2] ++; + } + dir_i_ = (dirs[0] > dirs[1]) ? -1 : 1; + for (iter_top(stems,i); i.ok(); i++) { + i->dir = dir_i_; + } +} + +/* + should use minimum energy formulation (cf linespacing) + */ +void +Beam::solve_slope() +{ + Array sinfo; + for (iter_top(stems,i); i.ok(); i++) { + i->set_default_extents(); + Stem_info info(i); + sinfo.push(info); + } + Real leftx = sinfo[0].x; + Least_squares l; + for (int i=0; i < sinfo.size(); i++) { + sinfo[i].x -= leftx; + l.input.push(Offset(sinfo[i].x, sinfo[i].idealy)); + } + + l.minimise(slope, left_pos); + Real dy = 0.0; + for (int i=0; i < sinfo.size(); i++) { + Real y = sinfo[i].x * slope + left_pos; + Real my = sinfo[i].miny; + + if (my - y > dy) + dy = my -y; + } + left_pos += dy; + left_pos *= dir_i_; + slope *= dir_i_; + + // URG + Real sl = slope*paper()->internote(); + paper()->lookup_p_->beam(sl, 20 PT); + slope = sl /paper()->internote(); +} + +void +Beam::set_stemlens() +{ + iter_top(stems,s); + Real x0 = s->hindex(); + for (; s.ok() ; s++) { + Real x = s->hindex()-x0; + s->set_stemend(left_pos + slope * x); + } +} + + +void +Beam::do_post_processing() +{ + solve_slope(); + set_stemlens(); +} + +void +Beam::set_grouping(Rhythmic_grouping def, Rhythmic_grouping cur) +{ + def.OK(); + cur.OK(); + assert(cur.children.size() == stems.size()); + + cur.split(def); + + Array b; + { + iter_top(stems,s); + Array flags; + for (; s.ok(); s++) { + int f = intlog2(abs(s->flag))-2; + assert(f>0); + flags.push(f); + } + int fi =0; + b= cur.generate_beams(flags, fi); + b.insert(0,0); + b.push(0); + assert(stems.size() == b.size()/2); + } + + iter_top(stems,s); + for (int i=0; i < b.size() && s.ok(); i+=2, s++) { + s->beams_left = b[i]; + s->beams_right = b[i+1]; + } +} + + +// todo. +Spanner * +Beam::do_break_at( PCol *, PCol *) const +{ + Beam *beam_p= new Beam(*this); + + return beam_p; +} + +void +Beam::do_pre_processing() +{ + left = (*stems.top()) ->pcol_l_; + right = (*stems.bottom())->pcol_l_; + assert(stems.size()>1); + if (!dir_i_) + set_default_dir(); + +} + + +Interval +Beam::width() const +{ + Beam * me = (Beam*) this; // ugh + return Interval( (*me->stems.top()) ->hindex(), + (*me->stems.bottom()) ->hindex() ); +} + +/* + beams to go with one stem. + */ +Molecule +Beam::stem_beams(Stem *here, Stem *next, Stem *prev)const +{ + assert( !next || next->hindex() > here->hindex() ); + assert( !prev || prev->hindex() < here->hindex() ); + Real dy=paper()->internote()*2; + Real stemdx = paper()->rule_thickness(); + Real sl = slope*paper()->internote(); + paper()->lookup_p_->beam(sl, 20 PT); + + Molecule leftbeams; + Molecule rightbeams; + + /* half beams extending to the left. */ + if (prev) { + int lhalfs= lhalfs = here->beams_left - prev->beams_right ; + int lwholebeams= here->beams_left beams_right ; + Real w = (here->hindex() - prev->hindex())/4; + Symbol dummy; + Atom a(dummy); + if (lhalfs) // generates warnings if not + a = paper()->lookup_p_->beam(sl, w); + a.translate(Offset (-w, -w * sl)); + for (int j = 0; j < lhalfs; j++) { + Atom b(a); + b.translate(Offset(0, -dir_i_ * dy * (lwholebeams+j))); + leftbeams.add( b ); + } + } + + if (next){ + int rhalfs = here->beams_right - next->beams_left; + int rwholebeams = here->beams_right beams_left; + + Real w = next->hindex() - here->hindex(); + Atom a = paper()->lookup_p_->beam(sl, w + stemdx); + + int j = 0; + for (; j < rwholebeams; j++) { + Atom b(a); + b.translate(Offset(0, -dir_i_ * dy * j)); + rightbeams.add( b ); + } + + w /= 4; + if (rhalfs) + a = paper()->lookup_p_->beam(sl, w); + + for (; j < rwholebeams + rhalfs; j++) { + Atom b(a); + b.translate(Offset(0, -dir_i_ * dy * j)); + rightbeams.add(b ); + } + + } + leftbeams.add(rightbeams); + return leftbeams; +} + + +Molecule* +Beam::brew_molecule_p() const return out; +{ + Real inter=paper()->internote(); + out = new Molecule; + Real x0 = stems.top()->hindex(); + + for (iter_top(stems,i); i.ok(); i++) { + PCursor p(i-1); + PCursor n(i+1); + Stem * prev = p.ok() ? p.ptr() : 0; + Stem * next = n.ok() ? n.ptr() : 0; + + Molecule sb = stem_beams(i, next, prev); + Real x = i->hindex()-x0; + sb.translate(Offset(x, (x * slope + left_pos)* inter)); + out->add(sb); + } + out->translate(Offset(x0 - left->hpos,0)); +} + +void +Beam::do_print()const +{ +#ifndef NPRINT + mtor << "slope " <breakable_b()) + retval.push(c); + assert(retval.top() == pscore_.cols.bottom().ptr()); + return retval; +} + +// construct an appropriate Spacing_problem and solve it. +Col_hpositions +Break_algorithm::solve_line(Line_of_cols curline) const +{ + Spacing_problem sp; + + sp.add_column(curline[0], true, 0.0); + for (int i=1; i< curline.size()-1; i++) + sp.add_column(curline[i]); + sp.add_column(curline.top(), true, linelength); + + // misschien moeven uit Spacing_problem? + for (iter_top(pscore_.suz,i); i.ok(); i++) { + sp.add_ideal(i); + } + Array the_sol=sp.solve(); + Col_hpositions col_hpos; + col_hpos.cols = curline; + col_hpos.energy = the_sol.pop(); + col_hpos.config = the_sol; + col_hpos.OK(); + return col_hpos; +} + +Break_algorithm::Break_algorithm(PScore&s) + :pscore_(s) +{ + linelength = s.paper_l_->linewidth; +} + +bool +Break_algorithm::feasible(Line_of_cols curline) const +{ + Real l =0; + for (int i=0; i < curline.size(); i++) + l +=curline[i]->width().length(); + return l < linelength; +} + +void +Break_algorithm::problem_OK() const +{ + if (!pscore_.cols.size()) + error("Score does not have any columns"); +#ifndef NDEBUG + iter_top(pscore_.cols,start); + PCursor end (pscore_.cols.bottom()); + + assert(start->breakable_b()); + assert(end->breakable_b()); +#endif +} diff --git a/lily/calcideal.cc b/lily/calcideal.cc new file mode 100644 index 0000000000..5ead08dd39 --- /dev/null +++ b/lily/calcideal.cc @@ -0,0 +1,53 @@ +#include "idealspacing.hh" +#include "score.hh" +#include "pscore.hh" +#include "paper-def.hh" +#include "score-column.hh" +#include "dimen.hh" + + +/** + this needs A LOT of rethinking. + + generate springs between columns. + + */ +void +Score::calc_idealspacing() +{ + iter_top(cols_,i); + + for (; i.ok(); i++) { + assert(i->used_b()); + PCursor j(i+1); + if (i->musical_b()) { + assert(j.ok()); + for (int n=0; n < i->durations.size(); n++) { + Moment d = i->durations[n]; + Real dist = paper_p_->duration_to_dist(d); + Real strength = i->durations[0]/i->durations[n]; + assert(strength <= 1.0); + + while (j->when() < d + i->when()) + j++; + Moment delta_desired = j->when() - (d+i->when()); + dist += paper_p_->duration_to_dist(delta_desired); + + pscore_p_->connect(i->pcol_l_, j->pcol_l_, dist, strength); + } + } else if (j.ok()) { + + /* attach i to the next column in use. This exists, since + the last col is breakable, and therefore in use + */ + + Moment d = j->when() - i->when(); + Real dist = (d) ? paper_p_->duration_to_dist(d) : 2 PT; // todo + + pscore_p_->connect(i->pcol_l_, j->pcol_l_, dist, (d) ? 1.0:1.0); + } + // !j.ok() might hold if we're at the last col. + } +} + + diff --git a/lily/clef-item.cc b/lily/clef-item.cc new file mode 100644 index 0000000000..528623eed6 --- /dev/null +++ b/lily/clef-item.cc @@ -0,0 +1,54 @@ +/* + clef-item.cc -- implement Clef_item + + source file of the LilyPond music typesetter + + (c) 1997 Han-Wen Nienhuys +*/ + +#include "clef-item.hh" +#include "string.hh" +#include "molecule.hh" +#include "paper-def.hh" +#include "lookup.hh" +#include "clef-reg.hh" + + + +Clef_item::Clef_item() +{ + change = true; + read("violin"); +} + +void +Clef_item::read(String t) +{ + type = t; + if (type == "violin") + y_off = 2; + if (type == "alto") + y_off = 4; + if (type == "tenor") + y_off = 6; + if (type == "bass") + y_off = 6; +} +void +Clef_item::read(Clef_register const &k) +{ + read(k.clef_type_str_); +} + +Molecule* +Clef_item::brew_molecule_p()const +{ + String t = type; + if (change) + t += "_change"; + Symbol s = paper()->lookup_p_->clef(t); + Molecule*output = new Molecule(Atom(s)); + output->translate(Offset(0, paper()->internote() * y_off)); + return output; +} + diff --git a/lily/clef-reg.cc b/lily/clef-reg.cc new file mode 100644 index 0000000000..2d9dcc112b --- /dev/null +++ b/lily/clef-reg.cc @@ -0,0 +1,107 @@ +/* + clef.cc -- implement Clef_register + + source file of the LilyPond music typesetter + + (c) 1997 Han-Wen Nienhuys , + Mats Bengtsson +*/ + +#include "clef-reg.hh" +#include "clef-item.hh" +#include "debug.hh" +#include "commandrequest.hh" +#include "time-description.hh" +#include "staff-column.hh" + +Clef_register::Clef_register() +{ + clef_p_ = 0; + + /* ugly hack to prevent segfault (daddy_reg_l_ == 0 at construction) */ + clef_type_str_ = ""; +} + +bool +Clef_register::set_type(String s) +{ + clef_type_str_ = s; + if (clef_type_str_ == "violin") { + c0_position_i_= -2; + } else if (clef_type_str_ == "alto") { + c0_position_i_= 4; + } else if (clef_type_str_ == "tenor") { + c0_position_i_= 6; + } else if (clef_type_str_ == "bass") { + c0_position_i_= 10; + }else + return false; + *get_staff_info().c0_position_i_ = c0_position_i_; + + return true; +} + +void +Clef_register::read_req(Clef_change_req*c_l) +{ + if (!set_type(c_l->clef_str_)) + error("unknown clef type ", c_l->defined_ch_c_l_); +} + +bool +Clef_register::try_request(Request * r_l) +{ + Command_req* creq_l= r_l->command(); + if (!creq_l || !creq_l->clefchange()) + return false; + + clef_req_l_ = creq_l->clefchange(); + + // do it now! Others have to read c0_pos. + read_req(creq_l->clefchange()); + return true; +} + +void +Clef_register::process_requests() +{ + const Time_description *time_l = get_staff_info().time_c_l_; + if (!clef_req_l_ && (!time_l->whole_in_measure_|| !time_l->when_)) { + clef_p_ = new Clef_item; + clef_p_->change = false; + } else if (clef_req_l_) { + clef_p_ = new Clef_item; + clef_p_->change = true; + } + if (clef_p_) { + clef_p_->read(*this); + announce_element(Staff_elem_info(clef_p_, + clef_req_l_)); + } +} + +void +Clef_register::pre_move_processing() +{ + if (!clef_p_) + return; + if (clef_p_->change) { + Clef_item* post_p = new Clef_item(*clef_p_); + post_p->change = false; + typeset_breakable_item(new Clef_item(*clef_p_), + clef_p_, post_p); + } else { + typeset_breakable_item(0, 0, clef_p_); + } + clef_p_ = 0; +} + +void +Clef_register::post_move_processing() +{ + clef_req_l_ = 0; + /* not in ctor, since the reg might not be linked in.*/ + if (clef_type_str_ == "") { + set_type("violin"); + } +} diff --git a/lily/colhpos.cc b/lily/colhpos.cc new file mode 100644 index 0000000000..530e4d4483 --- /dev/null +++ b/lily/colhpos.cc @@ -0,0 +1,35 @@ +#include "colhpos.hh" +#include "real.hh" +#include "debug.hh" +#include "const.hh" +#include "vector.hh" + +Col_hpositions::Col_hpositions() +{ + energy = INFTY; +} + +void +Col_hpositions::add( PCol*c) +{ + cols.push(c); +} + +void +Col_hpositions::print() const +{ +#ifndef NPRINT + mtor << "energy : " << energy << '\n'; + mtor << "line of " << config.size() << " cols\n"; + Vector v(config); + mtor << v; +#endif +} + +void +Col_hpositions::OK()const +{ +#ifndef NDEBUG + assert(config.size() == cols.size()); +#endif +} diff --git a/lily/commandrequest.cc b/lily/commandrequest.cc new file mode 100644 index 0000000000..5cf0912417 --- /dev/null +++ b/lily/commandrequest.cc @@ -0,0 +1,149 @@ +/* + commandrequest.cc -- implement Nonmusical reqs + + source file of the LilyPond music typesetter + + (c) 1997 Han-Wen Nienhuys +*/ + +#include "commandrequest.hh" +#include "debug.hh" +#include "musicalrequest.hh" + + +void +Cadenza_req::do_print()const +{ + mtor << on_b_; +} + +Cadenza_req::Cadenza_req(bool b) +{ + on_b_ =b; +} +/* *************** */ + + +int +Bar_req::compare(const Bar_req &c1)const +{ + return type_str_ == c1.type_str_; +} + +void +Bar_req::do_print() const +{ + mtor << type_str_; +} + +Bar_req::Bar_req(String s) +{ + type_str_ = s; +} + +Partial_measure_req::Partial_measure_req(Moment m) +{ + duration_ =m; +} +/* *************** */ +Meter_change_req::Meter_change_req() +{ + beats_i_ = 0; + one_beat_i_ =0; +} +void +Meter_change_req::set(int b,int o) +{ + beats_i_=b; + one_beat_i_=o; +} + +void +Timing_req::do_print()const{} + +void +Command_req::do_print()const{} +/* *************** */ +void +Barcheck_req::do_print() const{} + +/* *************** */ +void +Clef_change_req::do_print() const +{ + mtor << clef_str_ ; +} + +Clef_change_req::Clef_change_req(String s) +{ + clef_str_ = s; +} +/* *************** */ +void +Group_feature_req::do_print() const +{ + mtor << "stemdir " << stemdir_i_; +} + +Group_feature_req::Group_feature_req() +{ + stemdir_i_ = 0; +} + +void +Group_change_req::do_print()const +{ + mtor << "id : " << newgroup_str_; +} +/* *************** */ +void +Terminate_voice_req::do_print()const +{ +} + +/* *************** */ +void +Partial_measure_req::do_print() const +{ + mtor << duration_; +} + +void +Meter_change_req::do_print() const +{ + mtor << beats_i_ << "*" << one_beat_i_; +} + +/* *************** */ + +void +Measure_grouping_req::do_print() const +{ + for (int i=0; i < elt_length_arr_.size(); i++) { + mtor << beat_i_arr_[i] <<"*" << elt_length_arr_[i]<<" "; + } +} +/* *************** */ +void +Key_change_req::do_print() const +{ + for (int i=0; i < melodic_p_arr_.size(); i++) { + melodic_p_arr_[i]->print(); + } +} + +Key_change_req::Key_change_req() +{ +} +Key_change_req::Key_change_req(Key_change_req const&c) +{ + for (int i=0; i < c.melodic_p_arr_.size(); i++) { + melodic_p_arr_.push( c.melodic_p_arr_[i]->clone()->melodic() ); + } +} + +Key_change_req::~Key_change_req() +{ + for (int i=0; i < melodic_p_arr_.size(); i++) + delete melodic_p_arr_[i]; +} diff --git a/lily/complex-staff.cc b/lily/complex-staff.cc new file mode 100644 index 0000000000..bb13274449 --- /dev/null +++ b/lily/complex-staff.cc @@ -0,0 +1,37 @@ +#include "complex-staff.hh" +#include "complex-walker.hh" +#include "score.hh" +#include "pscore.hh" +#include "staffsym.hh" +#include "score-column.hh" + +const NO_LINES = 5; + +/** Aside from putting fields right, this generates the staff symbol. + */ +void +Complex_staff::set_output(PScore* pscore_l ) +{ + pstaff_l_ = new PStaff(pscore_l); + pscore_l_ = pscore_l; + pscore_l_->add(pstaff_l_); + + Staff_symbol *span_p = new Staff_symbol(NO_LINES); + + Score_column* col_last + =score_l_->find_col(score_l_->last(), false); + Score_column* col_first= + score_l_->find_col(0, false); + + span_p->set_extent(col_first->pcol_l_->postbreak_p_, + col_last->pcol_l_->prebreak_p_); + + pscore_l_->typeset_spanner(span_p, pstaff_l_); +} + + +Staff_walker * +Complex_staff::get_walker_p() +{ + return new Complex_walker(this); +} diff --git a/lily/complex-walker.cc b/lily/complex-walker.cc new file mode 100644 index 0000000000..0a76c81d0e --- /dev/null +++ b/lily/complex-walker.cc @@ -0,0 +1,108 @@ +/* + complex-walker.cc -- implement Complex_walker + + source file of the LilyPond music typesetter + + (c) 1997 Han-Wen Nienhuys +*/ + +#include "musicalrequest.hh" +#include "staff-column.hh" +#include "voice.hh" +#include "pscore.hh" +#include "complex-staff.hh" +#include "debug.hh" +#include "voice-group-regs.hh" +#include "voice-regs.hh" +#include "complex-walker.hh" +//#include "misc.hh" +#include "commandrequest.hh" +#include "walk-regs.hh" + +void +Complex_walker::do_post_move() +{ + walk_regs_p_->post_move_processing(); +} + +void +Complex_walker::do_pre_move() +{ + walk_regs_p_->pre_move_processing(); +} + +void +Complex_walker::do_announces() +{ + walk_regs_p_->do_announces(); +} + +bool +Complex_walker::try_command_request(Command_req *req_l) +{ + return walk_regs_p_->try_request(req_l); +} + +void +Complex_walker::try_request(Request*req) +{ + walk_regs_p_->try_request(req); +} + +void +Complex_walker::process_requests() +{ + Staff_column*c =ptr(); + + for (int i=0; i < c->creationreq_l_arr_.size(); i++) { + try_request(c->creationreq_l_arr_[i]); + } + for (int i=0; i < c->commandreq_l_arr_.size(); i++) { + try_request(c->commandreq_l_arr_[i]); + } + + for (int i=0; i < c->musicalreq_l_arr_.size(); i++) { + try_request(c->musicalreq_l_arr_[i]); + } + + regs_process_requests(); + do_announces(); +} + +void +Complex_walker::regs_process_requests() +{ + walk_regs_p_->process_requests(); +} + +void +Complex_walker::typeset_element(Staff_elem *elem_p) +{ + if (!elem_p) + return; + if (elem_p->spanner()) + pscore_l_->typeset_spanner(elem_p->spanner(), staff()->pstaff_l_); + else + ptr()->typeset_musical_item(elem_p->item()); +} + +Complex_walker::Complex_walker(Complex_staff*s) + : Staff_walker(s, s->pstaff_l_->pscore_l_) +{ + walk_regs_p_ = new Walker_registers(this); + do_post_move(); +} + + +Complex_walker::~Complex_walker() +{ +} + +Complex_staff* +Complex_walker::staff() +{ + return (Complex_staff*) staff_l_; +} + + + diff --git a/lily/debug.cc b/lily/debug.cc new file mode 100644 index 0000000000..01a35bd140 --- /dev/null +++ b/lily/debug.cc @@ -0,0 +1,59 @@ +#include +#include +#include +#include +#include "debug.hh" +#include "dstream.hh" +#include "vector.hh" + +Dstream *monitor=0; +ostream * nulldev =0; + +struct _Dinit { + _Dinit() { + nulldev = new ofstream("/dev/null"); + monitor = new Dstream(&cout,".dstreamrc"); + } + ~_Dinit() { + delete nulldev; + delete monitor; + } +} dinit; + + + +/* + want to do a stacktrace . + */ +void +mynewhandler() +{ + assert(false); +} + +void +float_handler(int) +{ + cerr << "Floating point exception .. \n"<< flush; + assert(false); +} + +void +debug_init() +{ +#ifndef NDEBUG + set_new_handler(&mynewhandler); +#endif + set_matrix_debug(*monitor); + signal(SIGFPE, float_handler); +} + +bool check_debug=false; + +void +set_debug(bool b) +{ + check_debug =b; +} + + diff --git a/lily/dimen.cc b/lily/dimen.cc new file mode 100644 index 0000000000..9489ae9a1e --- /dev/null +++ b/lily/dimen.cc @@ -0,0 +1,39 @@ +#include +#include "dimen.hh" +#include "debug.hh" +#include "string.hh" + +Real +parse_dimen(String dim) +{ + int i=dim.length_i()-1; + const char *s = dim; + while (i > 0 && (isspace(s[i]) || isalpha(s[i])) ){ + i--; + } + String unit(s + i+1); + return convert_dimen(dim.value_f(), unit); +} + + +Real +convert_dimen(Real quant, String unit) +{ + if (unit == "cm") + return quant * CM_TO_PT; + if (unit == "pt") + return quant; + if (unit == "mm") + return quant*CM_TO_PT/10; + if (unit == "in") + return quant * INCH_TO_PT; + error ("unknown length unit: `" + unit+"'"); +} + +String +print_dimen(Real r) +{ + String s(r); + s += "pt "; + return s; +} diff --git a/lily/directional-spanner.cc b/lily/directional-spanner.cc new file mode 100644 index 0000000000..7e2bb7c878 --- /dev/null +++ b/lily/directional-spanner.cc @@ -0,0 +1,6 @@ +#include "directional-spanner.hh" + +Directional_spanner::Directional_spanner() +{ + dir_i_ = 0; +} diff --git a/lily/grouping.cc b/lily/grouping.cc new file mode 100644 index 0000000000..bc665a19c0 --- /dev/null +++ b/lily/grouping.cc @@ -0,0 +1,350 @@ +/* + grouping.cc -- implement Rhythmic_grouping + + source file of the LilyPond music typesetter + + (c) 1997 Han-Wen Nienhuys +*/ + +#include "debug.hh" +#include "grouping.hh" +#include "interval.hh" + +void +Rhythmic_grouping::init() +{ + interval_ = 0; + children.set_size(0); +} + +void +Rhythmic_grouping::OK()const +{ +#ifndef NDEBUG + assert(bool(children.size()) != bool(interval_)); + + for (int i= 0; i < children.size(); i++) { + children[i]->OK(); + if (i>0) + assert(children[i-1]->interval().right == + children[i]->interval().left); + } +#endif +} + +Moment +Rhythmic_grouping::length() const +{ + return interval().length(); +} + +MInterval +Rhythmic_grouping::interval()const +{ + if (interval_) + return *interval_; + else + return + MInterval(children[0]->interval().left, + children.top()->interval().right); +} + +void +Rhythmic_grouping::split(Rhythmic_grouping r) +{ + if (interval_) + return ; + + r.intersect(interval()); + split(r.intervals()); + + for (int i= 0; i < children.size(); i++) { + if (!children[i]->interval_) { + Rhythmic_grouping here(r); + children[i]->split(here); + } + } +} + + +Array +Rhythmic_grouping::intervals() +{ + Array r; + if (interval_ || children.size() == 1) { + MInterval i(interval()); + MInterval r1(i), r2(i); + r1.right = r2.left = i.center(); + r.push(r1); r.push(r2); + } else { + for (int i=0; i < children.size(); i++) + r.push(children[i]->interval()); + } + return r; +} + +void +Rhythmic_grouping::intersect(MInterval t) +{ + if (interval_) { + interval_->intersect(t); + return; + } + + for (int i=0; i < children.size(); i++) { + MInterval inter = intersection(t, children[i]->interval()); + if (inter.empty() || inter.length() <= Rational( 0 )) { + delete children[i]; + children[i] =0; + } else { + children[i]->intersect(t); + } + } + for (int i=0; i < children.size(); ) { + if (!children[i]) + children.del(i); + else + i++; + } + +} + +/** + Put our children in branches of #this#. + The min and max time intervals coincide with elements of #splitpoints# + + I really should be documenting what is happening here, but I find + that difficult, since I don't really understand what's going on here. + + */ +void +Rhythmic_grouping::split(Array splitpoints) +{ + //check on splitpoints.. + int j = 0, i = 0, starti = 0, startj = 0; + + Array ch; + while (1) { + if ( i >= children.size() || j >= splitpoints.size()) + break; + + assert( + children[starti]->interval().left== splitpoints[startj].left); + if (children[i]->interval().right < splitpoints[j].right) { + i ++; + } else if (children[i]->interval().right > splitpoints[j].right ) { + j ++; + } else { + + if (i == starti) { + ch.push(children[i]); + } else { + Rhythmic_grouping *newchild=new Rhythmic_grouping( + children.subvec(starti, i+1)); + + ch.push(newchild); + } + i ++; + j++; + starti = i; + startj = j; + + + } + } + if (ch.size() != 1) + children = ch; + } + + +Rhythmic_grouping::Rhythmic_grouping(MInterval t, int n) +{ + init(); + if (n == 1 || !n) { + interval_ = new MInterval(t); + return; + } + Moment dt = t.length()/Rational(n); + MInterval basic = MInterval(t.left, t.left+dt); + for (int i= 0; i < n; i++) + children.push(new Rhythmic_grouping( dt*Rational(i) + basic )); +} + + +Rhythmic_grouping::Rhythmic_grouping(Array r) + :children(r) +{ + interval_ =0; +} + +Rhythmic_grouping::~Rhythmic_grouping() +{ + junk(); +} + +void +Rhythmic_grouping::copy(Rhythmic_grouping const&s) +{ + interval_ = (s.interval_)? new MInterval(*s.interval_) : 0; + for (int i=0; i < s.children.size(); i++) + children.push(new Rhythmic_grouping(*s.children[i])); +} + +void +Rhythmic_grouping::operator=(Rhythmic_grouping const &s) +{ + junk(); + copy(s); +} + +Rhythmic_grouping::Rhythmic_grouping(Rhythmic_grouping const&s) +{ + init(); + copy(s); +} + +void +Rhythmic_grouping::junk() +{ + delete interval_; + for (int i=0; i < children.size(); i++) + delete children[i]; + init(); +} + +void +Rhythmic_grouping::print()const +{ +#ifndef NPRINT + mtor << "{ \n"; + if (interval_) + mtor<<" Interval "<< interval_->str(); + for (int i=0; i < children.size(); i++) { + children[i]->print(); + } + mtor << "}\n"; +#endif +} + +bool +Rhythmic_grouping::child_fit_query(Moment start) +{ + if (children.size()) + return ( children.top()->interval().right== start); + + return true; +} + +void +Rhythmic_grouping::add_child(Moment start, Moment len) +{ + Moment stop = start+len; + + assert(child_fit_query(start)); + children.push(new Rhythmic_grouping(MInterval(start, stop))); +} + +Rhythmic_grouping::Rhythmic_grouping() +{ + interval_ =0; +} + +int +min_elt(Array v) +{ + int i = 1000; // ugh + for (int j = 0 ; j < v.size(); j++) + i = i +Rhythmic_grouping::generate_beams(Array flags, int &flagidx) +{ + assert (!interval_) ; + + Array< Array > children_beams; + for (int i=0; i < children.size(); i++) { + Array child_beams; + if (children[i]->interval_) { + int f = flags[flagidx++]; + child_beams.push(f); + } else { + child_beams = children[i]-> + generate_beams(flags, flagidx); + } + children_beams.push(child_beams); + } + Array beams; + int lastm, m, nextm; + for (int i=0; i < children_beams.size(); i++) { + bool add_left = (i >0); + bool add_right = (i < children_beams.size() -1); + + if (!i) + m = min_elt(children_beams[i]); + if (add_right) + nextm = min_elt(children_beams[i+1]); + + if (children_beams[i].size() == 1) { + if (add_right) + beams.push(m); + if (add_left) + beams.push(m); + } else { + if (add_left) + beams.push(lastm translate(m); +} + +void +Rhythmic_grouping::extend(MInterval m)const +{ + assert(m.left >= interval().left); + while (m.right >interval().right ) { + Array a(children); + for (int i=0; i < a.size(); i++) { + a[i] =new Rhythmic_grouping(*children[i]); + a[i]->translate(children.top()->interval().right); + } + ((Rhythmic_grouping*)this)->children.concat(a); + } + assert(m.right <= interval().right); + OK(); +} + +Rhythmic_grouping +parse_grouping(Array beat_i_arr, Array elt_length_arr) +{ + Moment here =0; + assert(beat_i_arr.size() == elt_length_arr.size()); + + Array children; + for (int i=0; i < beat_i_arr.size(); i++) { + Moment last = here; + here += elt_length_arr[i] * Moment(beat_i_arr[i]); + children.push( + new Rhythmic_grouping(MInterval(last, here), + beat_i_arr[i] )); + } + return Rhythmic_grouping(children); +} + diff --git a/lily/groupregs.cc b/lily/groupregs.cc new file mode 100644 index 0000000000..e69de29bb2 diff --git a/lily/headreg.cc b/lily/headreg.cc new file mode 100644 index 0000000000..dc5d72d572 --- /dev/null +++ b/lily/headreg.cc @@ -0,0 +1,76 @@ +/* + headreg.cc -- part of LilyPond + + (c) 1997 Han-Wen Nienhuys +*/ +#include "rest.hh" +#include "notehead.hh" +#include "headreg.hh" +#include "paper-def.hh" +#include "complex-walker.hh" +#include "musicalrequest.hh" + +Notehead_register::Notehead_register() +{ + note_p_ = 0; + set_feature(Features::dir(0)); + post_move_processing(); +} + +bool +Notehead_register::try_request(Request *req_l) +{ + if (req_l->note() || req_l->rest()) + note_req_l_=req_l->rhythmic(); + else + return false; + + return true; +} +void +Notehead_register::set_feature(Features d) +{ + if(d.direction_i_ || d.initialiser_b_) + dir_i_ = d.direction_i_; +} + +void +Notehead_register::process_requests() +{ + if (!note_req_l_) + return; + + + if (note_req_l_->note()) { + Notehead*n_p = new Notehead(8); // ugh + note_p_ = n_p; + n_p->set_rhythmic(note_req_l_->rhythmic()); + n_p->position = note_req_l_->note()->height() + + *get_staff_info().c0_position_i_; + } else { + note_p_ = new Rest ( note_req_l_->rhythmic()->balltype, + note_req_l_->rhythmic()->dots); + if (note_req_l_->rhythmic()->balltype <= 2) + note_p_->translate( + Offset(0, + 6 * paper()->internote())); + } + Staff_elem_info itinf(note_p_,note_req_l_); + announce_element(itinf); +} + +void +Notehead_register::pre_move_processing() +{ + if (note_p_) { + if (dir_i_ && note_p_->name() == Rest::static_name()) + note_p_->translate(Offset(0, 4*dir_i_ * paper()->internote())); + typeset_element(note_p_); + note_p_ = 0; + } +} +void +Notehead_register::post_move_processing() +{ + note_req_l_ = 0; +} diff --git a/lily/idealspacing.cc b/lily/idealspacing.cc new file mode 100644 index 0000000000..3ceaff1e6d --- /dev/null +++ b/lily/idealspacing.cc @@ -0,0 +1,31 @@ +#include "idealspacing.hh" +#include "pcol.hh" +#include "pscore.hh" +#include "pstaff.hh" +#include "debug.hh" + +void +Idealspacing::print() const +{ +#ifndef NPRINT + mtor << "idealspacing {" ; + mtor << "distance "<rank() << " right " << right->rank() << "}\n"; +#endif +} + +Idealspacing::Idealspacing(const PCol * l,const PCol * r) +{ + space = 0.0; + hooke = 0.0; + left = l; + right = r; +} + +void +Idealspacing::OK() const +{ +#ifndef NDEBUG + assert(hooke >= 0 && left && right); +#endif +} diff --git a/lily/identifier.cc b/lily/identifier.cc new file mode 100644 index 0000000000..59f1ff5d83 --- /dev/null +++ b/lily/identifier.cc @@ -0,0 +1,56 @@ +/* + identifier.cc -- implement identifier and derived classes + + source file of the LilyPond music typesetter + + (c) 1997 Han-Wen Nienhuys +*/ + +#include + +#include "identifier.hh" +#include "lexer.hh" +#include "debug.hh" + +void +Identifier::error(String expect) +{ + String e("Wrong identifier type: "); + e += String(classname()) + "(expected " + expect + ")"; + ::error(e); +} + +void +Identifier::print()const +{ + mtor << "identifier \'" << name << "\'="; + do_print(); +} + +/* ugh. */ +#define DEFAULT_PRINT(Class, Content_type, accessor) \ +void \ +Class::do_print() const { \ + ((Class*)this)->accessor(false)->print(); \ +} \ +class Class + +DEFAULT_PRINT(Script_id, Script_def, script); +DEFAULT_PRINT(Lookup_id, Lookup, lookup); +DEFAULT_PRINT(Symtables_id, Symtables, symtables); +DEFAULT_PRINT(Staff_id, Input_staff, staff); +DEFAULT_PRINT(M_chord_id, Music_general_chord, mchord); +DEFAULT_PRINT(M_voice_id, Music_voice, mvoice); + +void +Real_id::do_print() const +{ + Identifier::print(); + mtor << *((Real_id*)this)->real(false)<< "\n"; +} + +void +Notetab_id::do_print() const +{ + mtor << "unknown" << "\n"; +} diff --git a/lily/include/Makefile b/lily/include/Makefile new file mode 100644 index 0000000000..fa2827b30a --- /dev/null +++ b/lily/include/Makefile @@ -0,0 +1,23 @@ +# lily/include/Makefile + +# subdir level: +# +depth = ../.. +# + +# identify module: +# +MODULE_NAME = lilypond +MAJOR_VERSION = $(TOPLEVEL_MAJOR_VERSION) +MINOR_VERSION = $(TOPLEVEL_MINOR_VERSION) +PATCH_LEVEL = $(TOPLEVEL_PATCH_LEVEL) +# use to send patches, always empty for released version: +MY_PATCH_LEVEL = $(TOPLEVEL_MY_PATCH_LEVEL) +build = ./$(depth)/lily/.build +# + +# generic stuff/Makefile +# +include ./$(depth)/make/Include.make +# + diff --git a/lily/include/bar-reg.hh b/lily/include/bar-reg.hh new file mode 100644 index 0000000000..c73e5d1f4f --- /dev/null +++ b/lily/include/bar-reg.hh @@ -0,0 +1,31 @@ +/* + bar-reg.hh -- declare Bar_register + + source file of the LilyPond music typesetter + + (c) 1997 Han-Wen Nienhuys +*/ + + +#ifndef BARREG_HH +#define BARREG_HH +#include "register.hh" + +/** + generate bars. Either user ("|:"), or default (new measure) + */ +class Bar_register : public Request_register { + void split_bar(Bar *& pre, Bar * no, Bar * &post); +public: + Bar_req * bar_req_l_; + Bar * bar_p_; + + virtual bool try_request(Request *req_l); + virtual void process_requests(); + virtual void pre_move_processing(); + virtual void post_move_processing(); + Bar_register(); + NAME_MEMBERS(Bar_register); +}; + +#endif // BARREG_HH diff --git a/lily/include/bar.hh b/lily/include/bar.hh new file mode 100644 index 0000000000..3727358d96 --- /dev/null +++ b/lily/include/bar.hh @@ -0,0 +1,20 @@ +/* + bar.hh -- part of LilyPond + + (c) 1996,97 Han-Wen Nienhuys +*/ + +#ifndef BAR_HH +#define BAR_HH +#include "item.hh" + +struct Bar: Item { + String type; + + Bar(String type); +NAME_MEMBERS(Bar); + void do_print() const; + Molecule*brew_molecule_p()const; +}; +#endif // BAR_HH + diff --git a/lily/include/beam.hh b/lily/include/beam.hh new file mode 100644 index 0000000000..8eb2f148b5 --- /dev/null +++ b/lily/include/beam.hh @@ -0,0 +1,51 @@ +/* + beam.hh -- part of LilyPond + + (c) 1996,97 Han-Wen Nienhuys +*/ + +#ifndef BEAM_HH +#define BEAM_HH +#include "proto.hh" +#include "directional-spanner.hh" +#include "plist.hh" + +/** a beam connects multiple stems Beam adjusts the stems its owns to + make sure that they reach the beam and that point in the correct + direction */ +struct Beam: public Directional_spanner { + PointerList stems; + /// the slope of the beam in posns / point (dimension) + Real slope; + + /// position of leftmost end of beam + Real left_pos; + + + /* *************** */ +NAME_MEMBERS(Beam); + + virtual Interval width()const; + Offset center() const; + Spanner *do_break_at(PCol *, PCol *) const; + Beam(); + void add(Stem*); + + + void set_default_dir(); + void do_pre_processing(); + void do_post_processing(); + + void do_print() const; + void set_grouping(Rhythmic_grouping def, Rhythmic_grouping current); + void set_stemlens(); + ~Beam(); + +private: + Molecule stem_beams(Stem *here, Stem *next, Stem *prev)const; + void solve_slope(); + Molecule*brew_molecule_p()const; +}; + +#endif // BEAM_HH + diff --git a/lily/include/boxes.hh b/lily/include/boxes.hh new file mode 100644 index 0000000000..22a2eec3a5 --- /dev/null +++ b/lily/include/boxes.hh @@ -0,0 +1,31 @@ +/* + some 2D geometrical concepts +*/ + +#ifndef BOXES_HH +#define BOXES_HH + +#include "fproto.hh" +#include "real.hh" +#include "interval.hh" +#include "offset.hh" + +/// a square subset of Real^2 +struct Box { + Interval x, y; + + void translate(Offset o) { + x.translate(o.x); + y.translate(o.y); + } + /// smallest box enclosing #b# + void unite(Box b) { + x.unite(b.x); + y.unite(b.y); + } + Box(); + Box(Interval ix, Interval iy); +}; + + +#endif diff --git a/lily/include/break.hh b/lily/include/break.hh new file mode 100644 index 0000000000..886e2d788b --- /dev/null +++ b/lily/include/break.hh @@ -0,0 +1,44 @@ +/* + break.hh -- part of LilyPond + + (c) 1996,97 Han-Wen Nienhuys +*/ + +#ifndef BREAK_HH +#define BREAK_HH +#include "varray.hh" +#include "proto.hh" +#include "colhpos.hh" + +/** Class representation of an algorithm which decides where to put + the column, and where to break lines. */ +struct Break_algorithm { + PScore &pscore_; + Real linelength; + + /* *************** */ + + Break_algorithm(PScore&); + + /// check if the spacing/breaking problem is well-stated + void problem_OK()const; + + /// search all pcols which are breakable. + Line_of_cols find_breaks() const; + + /// helper: solve for the columns in #curline#. + Col_hpositions solve_line(Line_of_cols) const; + + /// does curline fit on the paper? + bool feasible(Line_of_cols)const; + + virtual Array solve()=0; +}; + +/// wordwrap type algorithm: move to next line if current is optimal. +struct Word_wrap : Break_algorithm { + virtual Array solve(); + Word_wrap(PScore&); +}; +#endif // BREAK_HH + diff --git a/lily/include/class-name.hh b/lily/include/class-name.hh new file mode 100644 index 0000000000..26da52dc0e --- /dev/null +++ b/lily/include/class-name.hh @@ -0,0 +1,19 @@ +/* + class-name.hh -- declare + + source file of the LilyPond music typesetter + + (c) 1997 Han-Wen Nienhuys +*/ + + +#ifndef CLASS_NAME_HH +#define CLASS_NAME_HH + +/// a macro to declare the classes name as a static and virtual function. +#define NAME_MEMBERS(c) \ +static const char *static_name(){ return #c; }\ +virtual const char *name() const{ return c::static_name(); } \ +int a_stupid_nonexistent_function_to_allow_the_semicolon_come_out() + +#endif // CLASS-NAME_HH diff --git a/lily/include/clef-item.hh b/lily/include/clef-item.hh new file mode 100644 index 0000000000..341204f8ea --- /dev/null +++ b/lily/include/clef-item.hh @@ -0,0 +1,31 @@ + +/* + clef-item.hh -- declare Clef_item + + (c) 1996,97 Han-Wen Nienhuys +*/ + +#ifndef CLEFITEM_HH +#define CLEFITEM_HH +#include "item.hh" + + +struct Clef_item : Item { + String type; + int y_off; + + /// is this a change clef (smaller size)? + bool change; + + + /* *************** */ +NAME_MEMBERS(Clef_item); + Clef_item(); + void read(Clef_register const&); + void read(String); + Molecule* brew_molecule_p()const; +}; + +#endif // CLEFITEM_HH + + diff --git a/lily/include/clef-reg.hh b/lily/include/clef-reg.hh new file mode 100644 index 0000000000..cc3a8a90e9 --- /dev/null +++ b/lily/include/clef-reg.hh @@ -0,0 +1,34 @@ +/* + clef.hh -- part of LilyPond + + (c) 1996,97 Han-Wen Nienhuys +*/ + +#ifndef CLEF_HH +#define CLEF_HH + +#include "scalar.hh" +#include "varray.hh" +#include "register.hh" + +/// where is c-0 in the staff? +class Clef_register : public Request_register { + Clef_item *clef_p_; + Clef_change_req * clef_req_l_; + +public: + int c0_position_i_; + String clef_type_str_; + + /* ************** */ + virtual void process_requests(); + virtual void pre_move_processing(); + virtual void post_move_processing(); + virtual bool try_request(Request*); + Clef_register(); + NAME_MEMBERS(Clef_register); + void read_req(Clef_change_req*); + bool set_type(String); +}; +#endif // CLEF_HH + diff --git a/lily/include/colhpos.hh b/lily/include/colhpos.hh new file mode 100644 index 0000000000..5398417ab1 --- /dev/null +++ b/lily/include/colhpos.hh @@ -0,0 +1,29 @@ +/* + colhpos.hh -- part of LilyPond + + (c) 1997 Han-Wen Nienhuys +*/ + +#ifndef COLHPOS_HH +#define COLHPOS_HH +#include "varray.hh" +#include "proto.hh" + +typedef Array Line_of_cols; + +struct Col_hpositions { + Line_of_cols cols; + Array config; + Real energy; + + /* ************** */ + void OK()const; + + Col_hpositions(); + void add( PCol*c); + void print() const; +}; + + +#endif // COLHPOS_HH + diff --git a/lily/include/commandrequest.hh b/lily/include/commandrequest.hh new file mode 100644 index 0000000000..71b8331661 --- /dev/null +++ b/lily/include/commandrequest.hh @@ -0,0 +1,117 @@ +/* + commandrequest.hh -- declare Non musical requests + + source file of the LilyPond music typesetter + + (c) 1997 Han-Wen Nienhuys +*/ + + +#ifndef COMMANDREQUEST_HH +#define COMMANDREQUEST_HH + +#include "request.hh" +#include "varray.hh" + +/** Request which are assumed to be "happening" before the + musical requests. */ +struct Command_req : virtual Request { + REQUESTMETHODS(Command_req, command); + + virtual Measure_grouping_req * measuregrouping() { return 0; } + virtual Clef_change_req * clefchange() { return 0; } + virtual Key_change_req * keychange() { return 0; } + virtual Partial_measure_req * partial() { return 0; } + virtual Meter_change_req * meterchange() { return 0; } + virtual Bar_req *bar() { return 0; } + virtual Cadenza_req *cadenza() { return 0; } + virtual Timing_req*timing() { return 0; } +}; + + +/** Baseclass for meter/partial req. It has to be handled by + Staff_{walker,column} baseclass. */ +struct Timing_req : Command_req { + REQUESTMETHODS(Timing_req, timing); +}; + + +struct Partial_measure_req : Timing_req { + Moment duration_; + + Partial_measure_req(Moment); + REQUESTMETHODS(Partial_measure_req, partial); +}; + +/** + todo: allow C meter + */ +struct Meter_change_req : Timing_req { + int beats_i_, one_beat_i_; + + Meter_change_req(); + void set(int,int); + REQUESTMETHODS(Meter_change_req, meterchange); +}; + +/// toggle Cadenza mode +struct Cadenza_req : Timing_req { + /// turn on? + bool on_b_; + Cadenza_req(bool); + REQUESTMETHODS(Cadenza_req,cadenza); +}; + +/// check if we're at start of a measure. +struct Barcheck_req : Timing_req { + + REQUESTMETHODS(Barcheck_req,barcheck); +}; + +struct Measure_grouping_req: Timing_req { + Array beat_i_arr_; + Array elt_length_arr_; + + REQUESTMETHODS(Measure_grouping_req, measuregrouping); +}; + +struct Group_change_req : Command_req { + String newgroup_str_; + REQUESTMETHODS(Group_change_req, groupchange); +}; + +/** draw a (repeat)-bar. This something different than #Barcheck_req#, + the latter should only happen at the start of a measure. */ +struct Bar_req : Command_req { + String type_str_; + Bar_req(String); + int compare(const Bar_req&)const; + REQUESTMETHODS(Bar_req,bar); +}; +struct Terminate_voice_req : Command_req { + REQUESTMETHODS(Terminate_voice_req,terminate); +}; + +struct Group_feature_req : Command_req { + int stemdir_i_; + Group_feature_req(); + REQUESTMETHODS(Group_feature_req, groupfeature); +}; + + +struct Key_change_req : Command_req { + Array melodic_p_arr_; + + Key_change_req(); + Key_change_req(Key_change_req const&); + ~Key_change_req(); + REQUESTMETHODS(Key_change_req, keychange); +}; + +struct Clef_change_req : Command_req { + String clef_str_; + Clef_change_req(String); + REQUESTMETHODS(Clef_change_req, clefchange); +}; + +#endif // COMMANDREQUEST_HH diff --git a/lily/include/complex-staff.hh b/lily/include/complex-staff.hh new file mode 100644 index 0000000000..0a37e3a5f7 --- /dev/null +++ b/lily/include/complex-staff.hh @@ -0,0 +1,25 @@ +/* + complex-staff.hh -- declare Complex_staff + + (c) 1996,1997 Han-Wen Nienhuys +*/ + +#ifndef COMPLEXSTAF_HH +#define COMPLEXSTAF_HH + + +#include "key.hh" +#include "staff.hh" +#include "staff-walker.hh" + +/// +struct Complex_staff : Staff { + + /* *************** */ + + virtual void set_output(PScore *); + virtual Staff_walker *get_walker_p(); +}; + +#endif // COMPLEXSTAF_HH + diff --git a/lily/include/complex-walker.hh b/lily/include/complex-walker.hh new file mode 100644 index 0000000000..861cee77f8 --- /dev/null +++ b/lily/include/complex-walker.hh @@ -0,0 +1,47 @@ +/* + complex-walker.hh -- declare Complex_walker + + (c) 1996,97 Han-Wen Nienhuys +*/ + +#ifndef COMPLEXWALKER_HH +#define COMPLEXWALKER_HH + +#include "proto.hh" +#include "staff-walker.hh" +#include "staff-elem-info.hh" + +/** + A staff walker which uses registers to decide what to print + */ +class Complex_walker: public Staff_walker { + bool try_command_request(Command_req *req_l); + void do_announces(); + void try_request(Request*req); + + + +public: + int c0_position_i_; + Walker_registers *walk_regs_p_; + + /* *************** */ + + void regs_process_requests(); + void typeset_element(Staff_elem *elem_p); + void announce_element(Staff_elem_info); + virtual void process_requests(); + virtual void do_post_move(); + virtual void do_pre_move(); + + Complex_walker(Complex_staff*); + ~Complex_walker(); + + Complex_staff *staff(); +private: +}; + + +#endif // COMPLEXWALKER_HH + + diff --git a/lily/include/config.hh b/lily/include/config.hh new file mode 100644 index 0000000000..ca44f294d7 --- /dev/null +++ b/lily/include/config.hh @@ -0,0 +1 @@ +#define LIBDIR "./" diff --git a/lily/include/const.hh b/lily/include/const.hh new file mode 100644 index 0000000000..9c2f3f9ccc --- /dev/null +++ b/lily/include/const.hh @@ -0,0 +1,12 @@ +/* + global constants + */ +#ifndef CONST_HH +#define CONST_HH +#include +#include "real.hh" + +const Real EPS=1e-7; // qlpsolve.hh +const int MAXITER=100; // qlpsolve.hh +const Real INFTY=HUGE_VAL; +#endif diff --git a/lily/include/dimen.hh b/lily/include/dimen.hh new file mode 100644 index 0000000000..a3f4e8876b --- /dev/null +++ b/lily/include/dimen.hh @@ -0,0 +1,21 @@ +#ifndef DIMEN_HH +#define DIMEN_HH + +#include "real.hh" +#include "string.hh" + +const Real INCH_TO_PT=72.0; +const Real CM_TO_PT=INCH_TO_PT/2.54; +const Real MM_TO_PT=CM_TO_PT/10; +const Real PT_TO_PT =1.0; + +#define PT *PT_TO_PT +#define MM *MM_TO_PT +#define CM *CM_TO_PT +#define INCH *INCH_TO_PT + +Real parse_dimen(String); +String print_dimen(Real); +Real convert_dimen(Real, String); +#endif + diff --git a/lily/include/directional-spanner.hh b/lily/include/directional-spanner.hh new file mode 100644 index 0000000000..9399b71c4d --- /dev/null +++ b/lily/include/directional-spanner.hh @@ -0,0 +1,26 @@ +/* + directional-spanner.hh -- part of LilyPond + + (c) 1996,97 Han-Wen Nienhuys +*/ + +#ifndef DIRECTIONALSPANNER_HH +#define DIRECTIONALSPANNER_HH + +#include "spanner.hh" + +/// a spanner which can be pointing "up" or "down" +struct Directional_spanner : Spanner{ + + /// -1 below heads, +1 above heads. + int dir_i_; + + /// offset of "center" relative to left-column/0-pos of staff + virtual Offset center() const=0; + virtual void set_default_dir()=0; + Directional_spanner(); + +}; + +#endif // DIRECTIONALSPANNER_HH + diff --git a/lily/include/glob.hh b/lily/include/glob.hh new file mode 100644 index 0000000000..7b8bb557d4 --- /dev/null +++ b/lily/include/glob.hh @@ -0,0 +1,9 @@ +#ifndef GLOB_HH +#define GLOB_HH +#include +#include +#include "real.hh" + +#include "proto.hh" +#include "const.hh" +#endif diff --git a/lily/include/grouping.hh b/lily/include/grouping.hh new file mode 100644 index 0000000000..06b4421b0a --- /dev/null +++ b/lily/include/grouping.hh @@ -0,0 +1,62 @@ +/* + grouping.hh -- part of LilyPond + + (c) 1996,97 Han-Wen Nienhuys +*/ + +#ifndef GROUPING_HH +#define GROUPING_HH + +#include "moment.hh" +#include "interval.hh" +#include "varray.hh" + +typedef Interval_t MInterval; + +/** data structure which represents rhythmic units this is a tree. It groupes notes according to rules + */ +struct Rhythmic_grouping { + Array children; + MInterval *interval_; + + /* *************** */ + + Array intervals(); + MInterval interval()const; + Moment length() const; + void intersect(MInterval); + + void operator=(Rhythmic_grouping const&); + Rhythmic_grouping(Rhythmic_grouping const&); + Rhythmic_grouping(MInterval, int n=1); + Rhythmic_grouping(); + Rhythmic_grouping(Array); + ~Rhythmic_grouping(); + + void add_child(Moment start, Moment len); + bool child_fit_query(Moment start); + void split(Rhythmic_grouping r); + void split(Array); + void split(int n); + + void print() const; + void OK() const; + + Array generate_beams(Array, int&); + + /** multiply self to span #i#. + In implementation, this isn't really const, but conceptually it is. + */ + void extend(MInterval i) const; + void translate(Moment); +private: + void init(); + void junk(); + void copy(Rhythmic_grouping const&); +}; + + +Rhythmic_grouping parse_grouping(Array beat_i_arr, Array elt_length_arr); + + +#endif diff --git a/lily/include/head-reg.hh b/lily/include/head-reg.hh new file mode 100644 index 0000000000..d5eb6fa5cd --- /dev/null +++ b/lily/include/head-reg.hh @@ -0,0 +1,24 @@ +/* + headreg.hh -- part of LilyPond + + (c) 1997 Han-Wen Nienhuys +*/ + + +#ifndef HEADREG_HH +#define HEADREG_HH +#include "register.hh" + +struct Notehead_register : Request_register { + Item* note_p_; + int dir_i_; + /* *************** */ + Notehead_register(Complex_walker*); + virtual bool try_request(Request *req_l) ; + virtual void process_request(); + virtual void do_pre_move_process(); + void set_dir(int); +}; + + +#endif // HEADREG_HH diff --git a/lily/include/headreg.hh b/lily/include/headreg.hh new file mode 100644 index 0000000000..eaa2d6f9d7 --- /dev/null +++ b/lily/include/headreg.hh @@ -0,0 +1,28 @@ +/* + headreg.hh -- part of LilyPond + + (c) 1997 Han-Wen Nienhuys +*/ + + +#ifndef HEADREG_HH +#define HEADREG_HH +#include "register.hh" + +struct Notehead_register : Request_register { + Item* note_p_; + Rhythmic_req * note_req_l_; + int dir_i_; + + /* *************** */ + Notehead_register(); + virtual bool try_request(Request *req_l) ; + virtual void process_requests(); + virtual void pre_move_processing(); + virtual void post_move_processing(); + void set_feature(Features); + NAME_MEMBERS(Notehead_register); +}; + + +#endif // HEADREG_HH diff --git a/lily/include/idealspacing.hh b/lily/include/idealspacing.hh new file mode 100644 index 0000000000..05f58ba9c8 --- /dev/null +++ b/lily/include/idealspacing.hh @@ -0,0 +1,30 @@ +/* + idealspacing.hh -- part of LilyPond + + (c) 1996,97 Han-Wen Nienhuys +*/ + +#ifndef IDEALSPACING_HH +#define IDEALSPACING_HH +#include "proto.hh" + +/// ideal spacing between two columns +struct Idealspacing { + + /// the ideal distance + Real space; + + /// Hooke's constant: how strong are the "springs" attached to columns + Real hooke; + + /// the two columns + const PCol *left, *right; + + void print()const; + void OK() const ; + Idealspacing(const PCol *left,const PCol *right); +}; + + +#endif // IDEALSPACING_HH + diff --git a/lily/include/identifier.hh b/lily/include/identifier.hh new file mode 100644 index 0000000000..1aa7f7d0c4 --- /dev/null +++ b/lily/include/identifier.hh @@ -0,0 +1,42 @@ + +/* + identifier.hh -- part of LilyPond + + (c) 1996,97 Han-Wen Nienhuys +*/ + +#ifndef IDENTIFIER_HH +#define IDENTIFIER_HH +#include "identparent.hh" +#include "symtable.hh" +#include "input-staff.hh" +#include "input-music.hh" +#include "notename.hh" +#include "lookup.hh" +#include "script-def.hh" + +#define make_id_class(Idclass, Class, accessor) \ +struct Idclass : Identifier {\ + virtual const char *classname() { return #Class; }\ + Idclass(String s, Class*st):Identifier(s) { data = st; }\ + virtual Class* accessor(bool copy) {\ + if (copy)\ + return new Class(* (Class*) data);\ + else\ + return (Class*) data;\ + }\ + ~Idclass() { delete accessor(false); }\ + virtual void do_print()const; \ +}\ + +make_id_class(Real_id, Real, real); +make_id_class(Script_id, Script_def, script); +make_id_class(Lookup_id, Lookup, lookup); +make_id_class(Symtables_id, Symtables, symtables); +make_id_class(Staff_id, Input_staff, staff); +make_id_class(M_chord_id, Music_general_chord, mchord); +make_id_class(M_voice_id, Music_voice, mvoice); +make_id_class(Notetab_id, Notename_tab, notename_tab); + +#endif // IDENTIFIER_HH + diff --git a/lily/include/identparent.hh b/lily/include/identparent.hh new file mode 100644 index 0000000000..3e6d566ee7 --- /dev/null +++ b/lily/include/identparent.hh @@ -0,0 +1,45 @@ +/* + identparent.hh -- part of LilyPond + + (c) 1996,97 Han-Wen Nienhuys +*/ + +#ifndef IDENTPARENT_HH +#define IDENTPARENT_HH + +#include "proto.hh" +#include "string.hh" + +/* boolean argument to accesor is copy_b..*/ +#define IDACCESSOR( Input_staff, staff)\ + virtual Input_staff * staff(bool) { error(#Input_staff); return 0; } + +struct Identifier { + void *data; + String name; + + Identifier(String n) : name(n) { } + virtual ~Identifier() {} + + void print()const; + virtual const char*classname() { return "new Identifier"; } + void error(String); + IDACCESSOR(Input_staff, staff) + IDACCESSOR(Input_music, music) + IDACCESSOR(Music_voice, mvoice) + IDACCESSOR(Script_def, script) + IDACCESSOR(Symtables, symtables) + IDACCESSOR(Music_general_chord, mchord) + IDACCESSOR(Lookup,lookup) + IDACCESSOR(Real,real) + IDACCESSOR(Notename_tab, notename_tab) +protected: + virtual void do_print()const=0; +private: + Identifier(Identifier const&){} + +}; +#endif // IDENTPARENT_HH + + + diff --git a/lily/include/input-music.hh b/lily/include/input-music.hh new file mode 100644 index 0000000000..1d7a8caa66 --- /dev/null +++ b/lily/include/input-music.hh @@ -0,0 +1,140 @@ +/* + input-music.hh -- part of LilyPond + + (c) 1996,97 Han-Wen Nienhuys +*/ + +#ifndef INPUTMUSIC_HH +#define INPUTMUSIC_HH + +#include "plist.hh" +#include "proto.hh" +#include "voice.hh" +#include "moment.hh" + +struct Voice_list : public PointerList { + void translate_time(Moment dt); +}; + +/** + + A set voices. + Input_music is anything that can simply be regarded as/converted to + a set of voices "cooperating" or independant. It has some basic + characteristics that real music has too: + + - it is rhythmic (it has a length, and can be translated horizontally) + - a pitch (it can be transposed) + + */ +struct Input_music { + virtual Voice_list convert()const=0; + void check_plet(Voice_element* velt_l); + virtual Moment length()const=0; + virtual void translate_time(Moment dt)=0; + virtual ~Input_music(){} + virtual void print() const =0; + virtual void set_default_group(String)=0; + virtual bool find_plet_start_bo(char c, Moment& moment_r) = 0; + virtual void set_plet_backwards(Moment& now_moment_r, Moment until_moment, int num_i, int den_i) = 0; + // virtual void transpose(...) const =0; + + + virtual Input_music *clone() const = 0; + virtual Simple_music *simple() { return 0; } +}; + +/// Simple music consists of one voice +struct Simple_music : Input_music { + Voice voice_; + + /* *** */ + virtual Simple_music*simple() { return this; } + void add(Voice_element*); + virtual void set_default_group(String g) { voice_.set_default_group(g); } + virtual Moment length()const; + virtual Voice_list convert()const; + virtual void translate_time(Moment dt); + virtual void print() const; + virtual bool find_plet_start_bo(char c, Moment& moment_r); + virtual void set_plet_backwards(Moment& now_moment_r, Moment until_moment, int num_i, int den_i); + virtual Input_music *clone() const { + return new Simple_music(*this); + } + +}; + +/// Complex_music consists of multiple voices +struct Complex_music : Input_music { + IPointerList elts; + /* *************** */ + virtual void set_default_group(String g); + void add(Input_music*); + Complex_music(); + Complex_music(Complex_music const &); + virtual void print() const ; + void concatenate(Complex_music*); + virtual bool find_plet_start_bo(char c, Moment& moment_r); + virtual void set_plet_backwards(Moment& now_moment_r, Moment until_moment, int num_i, int den_i); + +}; + + +/** + A voice like list of music. + + different music forms which start after each other ( concatenated, + stacked "horizontally ) + + */ + +struct Music_voice : Complex_music { + + + /* *************** */ + Moment length()const; + virtual void translate_time(Moment dt); + virtual Voice_list convert()const; + void add_elt(Voice_element*); + virtual Input_music *clone() const { + return new Music_voice(*this); + } + virtual void print() const ; +}; + +/** + Multiple musicstuff stacked on top of each other + chord like : + + - different music forms which start at the same time ( stacked "vertically" ) + + */ +struct Music_general_chord : Complex_music { + + + /* *************** */ + + virtual Moment length()const; + virtual Voice_list convert()const; + virtual void translate_time(Moment dt); + void add_elt(Voice_element*); + virtual Input_music *clone() const { + return new Music_general_chord(*this); + } + + virtual void print() const ; +}; + +struct Multi_voice_chord : Music_general_chord { + void set_default_group(String); + virtual Input_music *clone() const { + return new Multi_voice_chord(*this); + } +}; +struct Voice_group_chord : Music_general_chord { + + virtual Input_music *clone() const { + return new Voice_group_chord(*this); + } +}; +#endif // INPUTMUSIC_HH diff --git a/lily/include/input-score.hh b/lily/include/input-score.hh new file mode 100644 index 0000000000..4286f4b60b --- /dev/null +++ b/lily/include/input-score.hh @@ -0,0 +1,46 @@ +/* + input-score.hh -- declare + + source file of the LilyPond music typesetter + + (c) 1997 Han-Wen Nienhuys +*/ + + +#ifndef INPUTSCORE_HH +#define INPUTSCORE_HH + +#include "varray.hh" +#include "proto.hh" +#include "plist.hh" +#include "string.hh" + + +/// the total music def of one movement +struct Input_score { + /// defined where? + const char* defined_ch_c_l_; + int errorlevel_i_; + + /// paper_, staffs_ and commands_ form the problem definition. + Paper_def *paper_p_; + Midi_def* midi_p_; + IPointerList staffs_; + + Input_music * score_wide_music_p_; + + /* *************************************************************** */ + Input_score(); + Input_score(Input_score const&); + + void add(Input_staff*); + ~Input_score(); + /// construction + void set(Paper_def*); + void set(Midi_def* midi_p); + void print() const; + Score*parse(); + void set(Input_music*); +}; + +#endif diff --git a/lily/include/input-staff.hh b/lily/include/input-staff.hh new file mode 100644 index 0000000000..3b874a1b39 --- /dev/null +++ b/lily/include/input-staff.hh @@ -0,0 +1,35 @@ +/* + input-staff.hh -- declare Input_staff + + (c) 1996,97 Han-Wen Nienhuys +*/ + +#ifndef INPUTSTAFF_HH +#define INPUTSTAFF_HH + +#include "string.hh" +#include "plist.hh" +#include "varray.hh" +#include "proto.hh" + +struct Input_staff { + + const char * defined_ch_c_l_; + String type; + + IPointerList music_; + Input_music * score_wide_music_p_; + + /* *************** */ + ~Input_staff(); + void add(Input_music*m); + Input_staff(Input_staff const&); + Input_staff(String); + void set_score_wide(Input_music*m); + Staff* parse(Score*, Input_music *score_wide); + void print() const; +}; + + +#endif // INPUTSTAFF_HH + diff --git a/lily/include/item.hh b/lily/include/item.hh new file mode 100644 index 0000000000..d1fc8c8bfa --- /dev/null +++ b/lily/include/item.hh @@ -0,0 +1,32 @@ +#ifndef ITEM_HH +#define ITEM_HH + +#include "glob.hh" +#include "boxes.hh" +#include "string.hh" +#include "staff-elem.hh" + +/** + a horizontally fixed size element of the score + + Item is the datastructure for printables whose width is known + before the spacing is calculated + + NB. This doesn't mean an Item has to initialize the output field before + spacing calculation. + +*/ +struct Item : Staff_elem { + /// indirection to the column it is in + PCol * pcol_l_; + + /* *************** */ + virtual Item *item() { return this; } + Item(); + void do_print()const; + + NAME_MEMBERS(Item); +}; + + +#endif diff --git a/lily/include/key-item.hh b/lily/include/key-item.hh new file mode 100644 index 0000000000..e56af8e682 --- /dev/null +++ b/lily/include/key-item.hh @@ -0,0 +1,31 @@ +/* + key-item.hh -- part of LilyPond + + (c) 1996,97 Han-Wen Nienhuys +*/ + +#ifndef KEYITEM_HH +#define KEYITEM_HH + +#include "item.hh" +#include "varray.hh" + + +/// An item which places accidentals at the start of the line +struct Key_item : Item { + Array pitch; + Array acc; + int c_position; + + + /* *************** */ +NAME_MEMBERS(Key_item); + Key_item(int cposition); + void add(int pitch, int acc); + void read(const Key_register&); + void set_c_position(int); + void preprocess(); + Molecule* brew_molecule_p()const; +}; + +#endif // KEYITEM_HH diff --git a/lily/include/key-reg.hh b/lily/include/key-reg.hh new file mode 100644 index 0000000000..d8a96d066e --- /dev/null +++ b/lily/include/key-reg.hh @@ -0,0 +1,35 @@ +/* + key-reg.hh -- declare Key_register + + source file of the LilyPond music typesetter + + (c) 1997 Han-Wen Nienhuys +*/ + + +#ifndef KEYREG_HH +#define KEYREG_HH + +#include "register.hh" +#include "key.hh" + +struct Key_register : Request_register { + Key key_; + Key_change_req * keyreq_l_; + Key_item * kit_p_; + Array accidental_idx_arr_; + bool default_key_b_; + + virtual bool try_request(Request *req_l); + virtual void process_requests(); + virtual void pre_move_processing(); + virtual void post_move_processing(); + virtual void acknowledge_element(Staff_elem_info); + Key_register(); + NAME_MEMBERS(Key_register); +private: + + void read_req(Key_change_req * r); +}; + +#endif // KEYREG_HH diff --git a/lily/include/key.hh b/lily/include/key.hh new file mode 100644 index 0000000000..3d58629d5d --- /dev/null +++ b/lily/include/key.hh @@ -0,0 +1,39 @@ +/* + key.hh -- declare Key + + (c) 1996,97 Han-Wen Nienhuys +*/ + +#ifndef KEY_HH +#define KEY_HH + +#include "varray.hh" +#include "scalar.hh" + +/// administration of current key +class Key { + Array accidental_i_arr_; + + /* *************** */ + +public: + + Key(); + void set(int i, int acc); + int acc(int i)const { return accidental_i_arr_[i]; } +}; + +/// administration of accidentals +struct Local_key +{ + void reset(Key); + Key& oct(int); + Local_key(); + +private: + Array octaves; +}; + +#endif // KEY_HH + + diff --git a/lily/include/keyword.hh b/lily/include/keyword.hh new file mode 100644 index 0000000000..152d9dc15d --- /dev/null +++ b/lily/include/keyword.hh @@ -0,0 +1,27 @@ +/* + keyword.hh -- part of LilyPond + + (c) 1996,97 Han-Wen Nienhuys +*/ + +#ifndef KEYWORD_HH +#define KEYWORD_HH + +/* for the keyword table */ +struct Keyword_ent +{ + const char *name; + int tokcode; +}; + +struct Keyword_table +{ + Keyword_ent *table; + int maxkey; + Keyword_table(Keyword_ent *); + int lookup(const char *s) const; +}; + + +#endif // KEYWORD_HH + diff --git a/lily/include/leastsquares.hh b/lily/include/leastsquares.hh new file mode 100644 index 0000000000..35b1e1d34b --- /dev/null +++ b/lily/include/leastsquares.hh @@ -0,0 +1,24 @@ +/* + leastsquare.hh -- part of LilyPond + + (c) 1996,97 Han-Wen Nienhuys +*/ + +#ifndef LEASTSQUARE_HH +#define LEASTSQUARE_HH +#include "varray.hh" +#include "offset.hh" + + +/** + Least squares minimisation in 2 variables. + */ +struct Least_squares { + Array input; + void minimise(Real &coef, Real &offset); + void OK() const; +}; + + +#endif // LEASTSQUARE_HH + diff --git a/lily/include/lexer.hh b/lily/include/lexer.hh new file mode 100644 index 0000000000..6a9d21a98e --- /dev/null +++ b/lily/include/lexer.hh @@ -0,0 +1,51 @@ +/* + lexer.hh -- declare My_flex_lexer + + source file of the LilyPond music typesetter + + (c) 1997 Han-Wen Nienhuys +*/ + +#ifndef LEXER_HH +#define LEXER_HH +#include +#include "proto.hh" +#include "fproto.hh" +#include "varray.hh" +#include "string.hh" + +int yylex(); +void yyerror(const char *s); +bool busy_parsing(); +void kill_lexer(); +void set_lexer(); + +/// lexer with provisions for include files. +struct My_flex_lexer : yyFlexLexer { + + Array include_stack; + Assoc *the_id_tab; + Keyword_table * keytable; + Notename_tab * defaulttab; + int errorlevel_i_; + /* *************** */ + int ret_notename(int *p, String text, int octave_mod); + char const* here_ch_c_l(); + void set(Notename_tab *n); + int lookup_keyword(String); + void lookup_notename(int &large, int &small, String s); + void LexerError(const char *); + String spot() const; + Identifier*lookup_identifier(String s); + My_flex_lexer(); + void add_identifier(Identifier*i); + ~My_flex_lexer(); + void new_input(String s); + bool close_input(); + int yylex(); + void print_declarations() const; +}; + +extern My_flex_lexer *lexer; + +#endif diff --git a/lily/include/linespace.hh b/lily/include/linespace.hh new file mode 100644 index 0000000000..1479d1e936 --- /dev/null +++ b/lily/include/linespace.hh @@ -0,0 +1,106 @@ +#ifndef PROBLEM_HH +#define PROBLEM_HH + +#include "glob.hh" +#include "plist.hh" +#include "varray.hh" +#include "vector.hh" +#include "interval.hh" + +/// helper struct for #Spacing_problem# +struct Colinfo { + const PCol *pcol_; + const Real* fixpos; + Interval width; + + /* *************** */ + Colinfo(); + void operator=(Colinfo const&); + Colinfo(Colinfo const&); + ~Colinfo(); + Colinfo(const PCol*,const Real*); + void print() const; + bool fixed() const { return fixpos;} + Real fixed_position()const { return *fixpos; } + Real minright() const { return width.right; } + Real minleft() const { return -width.left; } +}; + + +/** the problem, given by the columns (which include constraints) and + intercolumn spacing. The problem is: + + Generate a spacing which + \begin{itemize} + \item + Satisfies spacing constraints (notes can't be printed through each other) + \item + Looks good, ie tries to conform to an ideal spacing as much as possible. + \end{itemize} + This is converted by regarding idealspacing as "springs" attached + to columns. The equilibrium of one spring is the ideal + distance. The columns have a size, this imposes "hard" constraints + on the distances. This transforms the problem into a quadratic + programming problem with linear constraints. + + The quality is given by the total potential energy in the + springs. The lower the energy, the better the configuration. +*/ +class Spacing_problem { + Array ideals; + Array cols; + + /// the index of #c# in #cols# + int col_id(const PCol *c) const; + + /// generate an (nonoptimal) solution + Vector find_initial_solution() const; + + /// check if problem is too tight + bool check_feasible() const; + + /// does #this# contain the column #w#? + bool contains(const PCol *w); + + /// make the energy function + void make_matrices(Matrix &quad, Vector &lin,Real&) const; + + /// generate the LP constraints + void make_constraints(Mixed_qp& lp) const; + +public: + /** solve the spacing problem + + @return the column positions, and the energy (last element) + + */ + Array solve() const; + + + /** + add a idealspacing to the problem. + + One pair of columns can have no, one or more idealspacings, + since they can be "summed" if the columns to which #i# refers are + not in this problem, the spacing is ignored. + */ + void add_ideal(const Idealspacing *i); + + + /** add a col to the problem. columns have to be added left to right. The column contains + info on it's minimum width. + */ + void add_column(const PCol *, bool fixed=false, Real fixpos=0.0); + + + + bool check_constraints(Vector v) const; + + Vector try_initial_solution() const; + void OK() const; + void print() const; + void print_ideal(const Idealspacing*)const; +}; + + +#endif diff --git a/lily/include/local-key-item.hh b/lily/include/local-key-item.hh new file mode 100644 index 0000000000..96bad9999e --- /dev/null +++ b/lily/include/local-key-item.hh @@ -0,0 +1,33 @@ +/* + local-key-item.hh -- part of LilyPond + + (c) 1996,97 Han-Wen Nienhuys +*/ + +#ifndef LOCALKEYITEM_HH +#define LOCALKEYITEM_HH +#include "item.hh" +#include "varray.hh" + +struct Local_acc { + int name , acc, octave; + static int compare(Local_acc&, Local_acc&); +}; + +struct Local_key_item : Item { +NAME_MEMBERS(Local_key_item); + Array accs; + Array support_items_; + int c0_position; + + /* *************** */ + + Local_key_item(int c0position); + void add(Item*); + void add(int oct, int pitch, int acc); + void add(Melodic_req*); + void do_pre_processing(); + Molecule* brew_molecule_p()const; +}; +#endif // LOCALKEYITEM_HH + diff --git a/lily/include/local-key-reg.hh b/lily/include/local-key-reg.hh new file mode 100644 index 0000000000..d0a2867a87 --- /dev/null +++ b/lily/include/local-key-reg.hh @@ -0,0 +1,25 @@ +/* + local-key-reg.hh -- declare Local_key_register + + (c) 1997 Han-Wen Nienhuys +*/ + + +#ifndef LOCALKEYREG_HH +#define LOCALKEYREG_HH +#include "register.hh" +#include "key.hh" + +struct Local_key_register : Request_register { + Local_key local_key_; + Local_key_item* key_item_p_; + const Key *key_c_l_; + /* *************** */ + virtual void process_requests(); + virtual void acknowledge_element(Staff_elem_info); + virtual void pre_move_processing(); + Local_key_register(); + NAME_MEMBERS(Local_key_register); +}; + +#endif // LOCALKEYREG_HH diff --git a/lily/include/lookup.hh b/lily/include/lookup.hh new file mode 100644 index 0000000000..524cdf1958 --- /dev/null +++ b/lily/include/lookup.hh @@ -0,0 +1,57 @@ +/* + lilypond, (c) 1996,97 Han-Wen Nienhuys +*/ +#ifndef LOOKUPSYMS_HH +#define LOOKUPSYMS_HH + +#include "symbol.hh" +#include "fproto.hh" +#include "scalar.hh" + +/// intuitive interface to symbol table +struct Lookup { + Symtables *symtables_; + String texsetting; + /* *************** */ + void add(String, Symtable*); + void print()const; + Real internote(); + + Symbol linestaff(int n, Real w); + Symbol fill(Box b); + Symbol beam_element(int,int,Real=0); + + /// round slope to closest TeXslope + Symbol beam(Real&,Real); + + /** + pos == 3 : 3 lines above staff (extending below note) + + pos == -3: below staff + */ + Symbol streepjes(int pos); + + Symbol meter(Array); + Symbol stem(Real y1_pos, Real y2_pos); + Symbol rule_symbol(Real height, Real width); + Symbol accidental(int); + Symbol ball(int); + Symbol flag(int); + Symbol rest(int); + Symbol clef(String); + Symbol bar(String); + Symbol dots(int); + Symbol slur(int dy, Real &dx, int dir); + Symbol half_slur(int dy, Real &dx, int dir, int xpart); + Symbol half_slur_middlepart(Real &dx, int dir); + Symbol big_slur(int dy, Real &dx, int dir); + Symbol text(String style, String text, int align = 1); + Symbol script(String idx); + Symbol hairpin(Real & width, bool decresc); + + Lookup(); + Lookup(Lookup const &); + ~Lookup(); +}; + +#endif diff --git a/lily/include/main.hh b/lily/include/main.hh new file mode 100644 index 0000000000..fe4f9ad8c2 --- /dev/null +++ b/lily/include/main.hh @@ -0,0 +1,19 @@ +#ifndef MAIN_HH +#define MAIN_HH +#include "proto.hh" + +void debug_init(); +void set_debug(bool); +void do_scores(); +void add_score(Input_score * s); +void set_default_output(String s); +Input_score* current_iscore_l(); +String find_file(String); +const char *get_version(); +extern String infile_str_g; +extern Source* source_l_g; +extern bool only_midi; + +extern String default_out_fn; + +#endif diff --git a/lily/include/meter-reg.hh b/lily/include/meter-reg.hh new file mode 100644 index 0000000000..6ebe18c282 --- /dev/null +++ b/lily/include/meter-reg.hh @@ -0,0 +1,29 @@ +/* + meter-reg.hh -- declare Meter_register + + source file of the LilyPond music typesetter + + (c) 1997 Han-Wen Nienhuys +*/ + + +#ifndef METERREG_HH +#define METERREG_HH +#include "register.hh" + +/** + generate meters. + */ +class Meter_register : public Request_register { +public: + Meter_change_req * meter_req_l_; + Meter * meter_p_; + + virtual bool try_request(Request *req_l); + virtual void process_requests(); + virtual void pre_move_processing(); + virtual void post_move_processing(); + Meter_register(); + NAME_MEMBERS(Meter_register); +}; +#endif // METERREG_HH diff --git a/lily/include/meter.hh b/lily/include/meter.hh new file mode 100644 index 0000000000..928434b28a --- /dev/null +++ b/lily/include/meter.hh @@ -0,0 +1,22 @@ +/* + meter.hh -- declare Meter + + (c) 1996,97 Han-Wen Nienhuys +*/ + +#ifndef METER_HH +#define METER_HH +#include "item.hh" +#include "varray.hh" +#include "scalar.hh" + +struct Meter: Item { + Array args; + /* *************** */ +NAME_MEMBERS(Meter); + + Meter(Array args) ; + Molecule*brew_molecule_p() const; +}; +#endif // METER_HH + diff --git a/lily/include/midi-output.hh b/lily/include/midi-output.hh new file mode 100644 index 0000000000..19457172cd --- /dev/null +++ b/lily/include/midi-output.hh @@ -0,0 +1,27 @@ +/* + midioutput.hh -- declare Midi_output + + source file of the LilyPond music typesetter + + (c) 1997 Han-Wen Nienhuys +*/ + + +#ifndef MIDIOUTPUT_HH +#define MIDIOUTPUT_HH +#include "pscore.hh" + +struct Midi_output { + Midi_output(Score* score_l, Midi_def* ); + + void do_staff(Staff*st_l, int count); + void header(); + void staffs(); + + Score* score_l_; + Midi_def* midi_l_; + Midi_stream* midi_stream_l_; +}; + +#endif // MIDIOUTPUT_HH + diff --git a/lily/include/misc.hh b/lily/include/misc.hh new file mode 100644 index 0000000000..00b742076e --- /dev/null +++ b/lily/include/misc.hh @@ -0,0 +1,26 @@ +#ifndef MISC_HH +#define MISC_HH + +#include "proto.hh" +#include "real.hh" +#include "moment.hh" +#include "scalar.hh" +#include "grouping.hh" + +Moment wholes(int dur, int dots); +double log_2(double x) ; +int intlog2(int d); +inline int +abs(int i){ + return (i < 0)?-i:i; +} +inline int +sign(int i) { + if (i<0) return -1; + else if (i) return 1; + else return 0; +} + +Interval itemlist_width(const Array &its); + +#endif diff --git a/lily/include/molecule.hh b/lily/include/molecule.hh new file mode 100644 index 0000000000..084321ce4e --- /dev/null +++ b/lily/include/molecule.hh @@ -0,0 +1,57 @@ +#ifndef MOLECULE_HH +#define MOLECULE_HH + +#include "proto.hh" +#include "plist.hh" +#include "boxes.hh" +#include "symbol.hh" + +/// a symbol which can be translated, and freely copied +struct Atom { + Offset off; + Symbol sym; + + /* *************** */ + + void translate(Offset o) { + off += o; + } + + /// how big is #this#? + Box extent() const; + Atom(Symbol s); + + void print() const; + + String TeXstring() const; +}; + + +/** a group of individually translated symbols. You can add molecules + to the top, to the right, etc. */ +struct Molecule { + IPointerList ats; // change to List? + + /* *************** */ + + Molecule() { } + Molecule(Atom a) { add(a) ; } + + void add_right(const Molecule &m); + void add_left(const Molecule &m); + void add_top(const Molecule &m); + void add_bottom(const Molecule &m); + void add(Molecule const &m); + void translate(Offset); + void add(Atom a) { ats.bottom().add(new Atom(a)); } + /// how big is #this#? + Box extent() const; + + String TeXstring() const; + + Molecule(const Molecule&s); + void print() const; +private: + void operator=(const Molecule&); +}; +#endif diff --git a/lily/include/musicalrequest.hh b/lily/include/musicalrequest.hh new file mode 100644 index 0000000000..240b72afd9 --- /dev/null +++ b/lily/include/musicalrequest.hh @@ -0,0 +1,198 @@ +/* + musicalrequests.hh -- declare Musical requests + + source file of the LilyPond music typesetter + + (c) 1997 Han-Wen Nienhuys +*/ + + +#ifndef MUSICALREQUESTS_HH +#define MUSICALREQUESTS_HH + +#include "request.hh" + + +/** + A request which is coupled to a #Voice_element# with nonzero duration. + Base class only + */ +struct Musical_req : virtual Request { + virtual Skip_req* skip() { return 0; } + REQUESTMETHODS(Musical_req, musical); +}; + + +struct Skip_req : Musical_req { + Moment duration_; + + virtual Moment duration() const; + REQUESTMETHODS(Skip_req, skip); +}; +/** a request with a duration. + This request is used only a base class. + */ +struct Rhythmic_req : virtual Musical_req { + int balltype; + int dots; + Moment plet_factor; + /* *************** */ + static int compare(const Rhythmic_req &, const Rhythmic_req &); + virtual Moment duration() const; + Rhythmic_req(); + Rhythmic_req(int,int); + REQUESTMETHODS(Rhythmic_req, rhythmic); +}; + +struct Spacing_req :virtual Request { + Moment next; + Real distance; + Real strength; + /* *************** */ + Spacing_req(); + REQUESTMETHODS(Spacing_req, spacing); +}; + +struct Blank_req : Spacing_req, Rhythmic_req { + REQUESTMETHODS(Spacing_req, spacing); + +}; + +/// Put a text above or below (?) this staff. +struct Text_req : virtual Musical_req { + /// preferred position (above/below) + int dir_i_; + /// the characteristics of the text + Text_def *tdef_p_; + /* *************** */ + Text_req(int d, Text_def*); + ~Text_req(); + Text_req(Text_req const&); + static int compare(const Text_req&,const Text_req&); + REQUESTMETHODS(Text_req,text); +}; + +/** Put a text in lyric_staff + @see Lyric_staff + */ +struct Lyric_req : public Rhythmic_req, Text_req { + Lyric_req(Text_def* t_p); + REQUESTMETHODS(Lyric_req, lreq_l); +}; + +/// request which has some kind of pitch +struct Melodic_req :virtual Musical_req +{ + /// 0 is c, 6 is b + int notename_i_; + /// 0 is central c + int octave_i_; + + /// 0 natural, 1 sharp, etc + int accidental_i_; + + /// force/supress printing of accidental. + bool forceacc_b_; + + /// return height from central c (in halflines) + int height()const; + /// return pitch from central c (in halfnotes) + int pitch()const; + Melodic_req(); + + REQUESTMETHODS(Melodic_req,melodic); +}; + +/// Put a note of specified type, height, and with accidental on the staff. +struct Note_req : Rhythmic_req, virtual Melodic_req { + + + Rhythmic_req* rhythmic() { return Rhythmic_req::rhythmic(); } + REQUESTMETHODS(Note_req, note); + }; + +/** +Put a rest on the staff. Why a request? It might be a good idea to not typeset the rest, if the paper is too crowded. +*/ +class Rest_req : public Rhythmic_req { +public: + REQUESTMETHODS(Rest_req,rest); +}; + +/** + attach a stem to the noteball. + Rhythmic_req parent needed to determine if it will fit inside a beam. + */ +struct Stem_req : Rhythmic_req { + /// preferred direction for the stem + int dir_i_; + Stem_req(int s, int dots); + REQUESTMETHODS(Stem_req,stem); +}; + +/** + Requests to start or stop something. + This type of request typically results in the creation of a #Spanner# +*/ +struct Span_req : Musical_req { + /// should the spanner start or stop, or is it unwanted? + enum { + NOSPAN, START, STOP + } spantype ; + static int compare(const Span_req &r1, const Span_req &r2); + REQUESTMETHODS(Span_req,span); + + Span_req(); + +}; + +/// request for backward plet generation +struct Plet_req : Request { + char type_c_; + int dur_i_; + int type_i_; + Plet_req(); + + REQUESTMETHODS(Plet_req,plet); +}; +/** +*/ + +/** Start / stop a beam at this note. if #nplet# is set, the staff will try to put an +appropriate number over the beam + */ +struct Beam_req : Span_req { + int nplet; + + /* *************** */ + REQUESTMETHODS(Beam_req,beam); + + Beam_req(); +}; + +/// a slur +struct Slur_req : Span_req { + REQUESTMETHODS(Slur_req,slur); + +}; + + +/**Put a script above or below this ``note''. eg upbow, downbow. Why a +request? These symbols may conflict with slurs and brackets, so this +also a request */ +struct Script_req : Musical_req { + int dir_i_; + Script_def *scriptdef_p_; + + /* *************** */ + static int compare(const Script_req &, const Script_req &); + Script_req(int d, Script_def*); + REQUESTMETHODS(Script_req,script); + ~Script_req(); + Script_req(Script_req const&); +}; + + + + +#endif // MUSICALREQUESTS_HH diff --git a/lily/include/notehead.hh b/lily/include/notehead.hh new file mode 100644 index 0000000000..d7a68e7798 --- /dev/null +++ b/lily/include/notehead.hh @@ -0,0 +1,45 @@ +/* + notehead.hh -- part of LilyPond + + (c) 1996,97 Han-Wen Nienhuys +*/ + +#ifndef NOTEHEAD_HH +#define NOTEHEAD_HH +#include "item.hh" + +/** + ball at the end of the stem +takes care of: + + * help lines + * proper placing of dots + + */ + +struct Notehead : Item { + NAME_MEMBERS(Notehead); + + int position; + /// -1 = lowest, 0 = inside, 1 = top + int extremal; + /// needed for the help-lines + int staff_size; + int dots; + int balltype; + int x_dir; + + /* *************** */ + + void set_rhythmic(Rhythmic_req *); + + /** + position of top line (5 linestaff: 8) + */ + Notehead(int staff_size); + void do_print()const; + static int compare(Notehead * const &a, Notehead *const &b) ; + Molecule* brew_molecule_p()const; +}; +#endif // NOTEHEAD_HH + diff --git a/lily/include/notename.hh b/lily/include/notename.hh new file mode 100644 index 0000000000..b533f4d360 --- /dev/null +++ b/lily/include/notename.hh @@ -0,0 +1,24 @@ +/* + notename.hh -- part of LilyPond + + (c) 1996,97 Han-Wen Nienhuys +*/ + +#ifndef NOTENAME_HH +#define NOTENAME_HH + +#include "string.hh" + +struct Notename_tab { + String notetab[7*5]; + + void set(int l, int s, String nm); + void lookup(int &large, int &small, String s); +}; + +void set_notename_tab(Notename_tab*n); +void lookup_notename(int &large, int &small, String s); + + +#endif // NOTENAME_HH + diff --git a/lily/include/offset.hh b/lily/include/offset.hh new file mode 100644 index 0000000000..e0b62bba76 --- /dev/null +++ b/lily/include/offset.hh @@ -0,0 +1,38 @@ +/* + offset.hh -- part of LilyPond + + (c) 1996,97 Han-Wen Nienhuys +*/ + +#ifndef OFFSET_HH +#define OFFSET_HH +#include "real.hh" + +/// 2d vector +struct Offset { + Real x,y; + + Offset operator+(Offset o)const { + Offset r(*this); + r+=o; + return r; + } + + Offset operator+=(Offset o) { + x+=o.x; + y+=o.y; + return *this; + } + Offset(Real ix , Real iy) { + x=ix; + y=iy; + } + Offset() { + x=0.0; + y=0.0; + } +}; + +#endif // OFFSET_HH + + diff --git a/lily/include/p-staff.hh b/lily/include/p-staff.hh new file mode 100644 index 0000000000..50a7f0c719 --- /dev/null +++ b/lily/include/p-staff.hh @@ -0,0 +1,25 @@ +#ifndef PSTAFF_HH +#define PSTAFF_HH + +#include "proto.hh" +#include "plist.hh" +#include "item.hh" +#include "symbol.hh" + +/// items grouped horizontally +struct PStaff { + PScore * pscore_l_; + + + PointerList spans; + PointerList its; + + /* *************** */ + void add(Item*i); + PStaff(PScore*); + +private: + PStaff(PStaff const&); +}; + +#endif diff --git a/lily/include/paper-def.hh b/lily/include/paper-def.hh new file mode 100644 index 0000000000..ae557258b0 --- /dev/null +++ b/lily/include/paper-def.hh @@ -0,0 +1,54 @@ +/* + paper-def.hh -- declare + + source file of the LilyPond music typesetter + + (c) 1997 Han-Wen Nienhuys +*/ + + +#ifndef Paper_def_HH +#define Paper_def_HH +#include "proto.hh" +#include "real.hh" +#include "string.hh" +#include "moment.hh" + + +/** symbols, dimensions and constants + + This struct takes care of all kinds of symbols, dimensions and + constants. Most of them are related to the point-size of the fonts, + so therefore, the lookup table for symbols is also in here. + + see TODO + */ +struct Paper_def { + Lookup *lookup_p_; + String outfile; + + Real linewidth; + + /// how much space does a whole note take (ideally?) + Real whole_width; + + /// ideal = geometric_ ^ log2(duration) + Real geometric_; + + /* *************** */ + void reinit(); + Paper_def(Lookup*); + void set(Lookup*); + ~Paper_def(); + Paper_def(Paper_def const&); + Real interline()const; + Real internote()const; + Real rule_thickness()const; + Real standard_height()const; + Real note_width() const; + void print() const; + Real duration_to_dist(Moment); +}; + +#endif // Paper_def_HH + diff --git a/lily/include/parseconstruct.hh b/lily/include/parseconstruct.hh new file mode 100644 index 0000000000..7b9e3e3ec2 --- /dev/null +++ b/lily/include/parseconstruct.hh @@ -0,0 +1,39 @@ +/* + parseconstruct.hh -- part of LilyPond + + (c) 1996,97 Han-Wen Nienhuys +*/ + +#ifndef PARSECONSTRUCT_HH +#define PARSECONSTRUCT_HH + +#include "proto.hh" + +extern char const* defined_ch_c_l; +extern char const* req_defined_ch_c_l; +void set_default_duration(int *); +void last_duration(int n); +void set_duration_mode(String s); +void get_default_duration(int *); +void set_default_octave(String); +void set_plet(int,int); +Voice_element * get_note_element(String,int * ,int *); +Voice_element* get_rest_element(String,int *); +Voice_element* get_word_element(Text_def*, int*); +void add_requests( Voice_element*v, Array&req); +Request* get_request(char); +void set_text_style(String); +Script_def* get_scriptdef(char); +Text_def*get_text(String s); +Request* get_plet_request( char c, int dur_i, int type_i ); +Request*get_script_req(int d , Script_def*def); +Request*get_text_req(int d , Text_def*def); +Request* get_stemdir_req(int); + + + + +Request*get_grouping_req(Array i_arr); + +#endif // PARSECONSTRUCT_HH + diff --git a/lily/include/parser.hh b/lily/include/parser.hh new file mode 100644 index 0000000000..3a3d4de3ef --- /dev/null +++ b/lily/include/parser.hh @@ -0,0 +1,86 @@ +typedef union { + Request * request; + Real real; + Identifier *id; + Voice *voice; + Voice_element *el; + String *string; + const char *consstr; + Paper_def *paper; + Midi_def* midi; + Input_music *music; + Music_general_chord *chord; + Music_voice *mvoice; + int i; + char c; + int ii[10]; + Moment *moment; + + Array * strvec; + Array *intvec; + Array *melreqvec; + Input_staff *staff; + Input_score *score; + Symtables * symtables; + Symtable * symtable; + Symbol * symbol; + Lookup*lookup; + Interval *interval; + Box *box; + Notename_tab *notename_tab; + Script_def * script; + Text_def * textdef; +} YYSTYPE; +#define VOICE 258 +#define STAFF 259 +#define SCORE 260 +#define TITLE 261 +#define BAR 262 +#define OUTPUT 263 +#define MULTIVOICE 264 +#define CM_T 265 +#define IN_T 266 +#define PT_T 267 +#define MM_T 268 +#define PAPER 269 +#define WIDTH 270 +#define METER 271 +#define UNITSPACE 272 +#define SKIP 273 +#define COMMANDS 274 +#define COMMAND 275 +#define GEOMETRIC 276 +#define START_T 277 +#define DURATIONCOMMAND 278 +#define OCTAVECOMMAND 279 +#define KEY 280 +#define CLEF 281 +#define TABLE 282 +#define VOICES 283 +#define STEM 284 +#define PARTIAL 285 +#define MUSIC 286 +#define GROUPING 287 +#define CADENZA 288 +#define END 289 +#define SYMBOLTABLES 290 +#define TEXID 291 +#define NOTENAMES 292 +#define SCRIPT 293 +#define TEXTSTYLE 294 +#define PLET 295 +#define GOTO 296 +#define MIDI 297 +#define TEMPO 298 +#define IDENTIFIER 299 +#define PITCHMOD 300 +#define DURATION 301 +#define RESTNAME 302 +#define NOTENAME 303 +#define REAL 304 +#define STRING 305 +#define DOTS 306 +#define INT 307 + + +extern YYSTYPE yylval; diff --git a/lily/include/pcol.hh b/lily/include/pcol.hh new file mode 100644 index 0000000000..4fac246e49 --- /dev/null +++ b/lily/include/pcol.hh @@ -0,0 +1,86 @@ +#ifndef COLS_HH +#define COLS_HH + +#include "glob.hh" +#include "boxes.hh" +#include "plist.hh" +#include "item.hh" + + +/** + stuff grouped vertically. + This is a class to address items vertically. It contains the data for: + \begin{itemize} + \item + unbroken score + \item + broken score + \item + the linespacing problem + \end{itemize} + */ + +struct PCol { + PointerList its; + PointerList stoppers, starters; + + + + /** prebreak is put before end of line. + if broken here, then (*this) column is discarded, and prebreak + is put at end of line, owned by Col + */ + PCol *prebreak_p_; + + /// postbreak at beginning of the new line + PCol *postbreak_p_; + + /** if this column is pre or postbreak, then this field points to + the parent. */ + PCol *daddy_l_; + + /// if lines are broken then this column is in #line# + const Line_of_score *line_l_; + + /// if lines are broken then this column x-coord #hpos# + Real hpos; + + PScore * pscore_l_; + + /* *************** */ + /// which one (left =0) + int rank() const; + + /// does this column have items + bool used_b() const; + + void add(Item *i); + + /// Can this be broken? true eg. for bars. + bool breakable_b()const; + + Interval width() const; + ~PCol(); + PCol(PCol * parent); + + /** + which col comes first?. + signed compare on columns. + + @return < 0 if c1 < c2. + */static int compare(const PCol &c1, const PCol &c2); + + + void OK() const; + void set_breakable(); + void print()const; +private: + PCol(PCol const&){} +}; + + +#include "compare.hh" +instantiate_compare(PCol &, PCol::compare); + + +#endif diff --git a/lily/include/pscore.hh b/lily/include/pscore.hh new file mode 100644 index 0000000000..b7ad49c0e1 --- /dev/null +++ b/lily/include/pscore.hh @@ -0,0 +1,106 @@ +// the breaking problem for a score. + +#ifndef PSCORE_HH +#define PSCORE_HH + +#include "colhpos.hh" +#include "varray.hh" +#include "pcol.hh" +#include "pstaff.hh" + + +/** all stuff which goes onto paper. notes, signs, symbols in a score can be grouped in two ways: + horizontally (staffwise), and vertically (columns). #PScore# + contains the items, the columns and the staffs. + */ + +struct PScore { + Paper_def *paper_l_; + + /// the columns, ordered left to right + IPointerList cols; + + /// the idealspacings, no particular order + IPointerList suz; + + /// the staffs ordered top to bottom + IPointerList staffs; + + /// all symbols in score. No particular order. + IPointerList its; + + /// if broken, the different lines + IPointerList lines; + + /// crescs etc; no particular order + IPointerList spanners; + + /// broken spanners + IPointerList broken_spans; + + /* *************** */ + /* CONSTRUCTION */ + + PScore(Paper_def*); + /// add a line to the broken stuff. Positions given in #config# + void set_breaking(Array); + + void add(PStaff *); + + + /** add an item. + add the item in specified containers. If breakstatus is set + properly, add it to the {pre,post}break of the pcol. + */ + void typeset_item(Item *item_p, PCol *pcol_l,PStaff*pstaf_l,int breakstatus=1); + + /// add a Spanner + void typeset_spanner(Spanner*, PStaff*); + + /// add to bottom of pcols + void add(PCol*); + void add_broken(Spanner*); + + /* INSPECTION */ + Array select_items(PStaff*, PCol*); + + /** + @return argument as a cursor of the list + */ + PCursor find_col(const PCol *)const; + + /* MAIN ROUTINES */ + void process(); + + /// last deed of this struct + void output(Tex_stream &ts); + + /* UTILITY ROUTINES */ + + /// get the spacing between c1 and c2, create one if necessary. + Idealspacing* get_spacing(PCol *c1, PCol *c2); + + /// connect c1 and c2 + void do_connect(PCol *c1, PCol *c2, Real distance_f, Real strength_f); + + /// connect c1 and c2 and any children of c1 and c2 + void connect(PCol* c1, PCol *c2, Real distance_f,Real strength_f= 1.0); + + /* STANDARD ROUTINES */ + void OK()const; + void print() const; +private: + /// before calc_breaking + void preprocess(); + + /// calculate where the lines are to be broken, and use results + void calc_breaking(); + + /// after calc_breaking + void postprocess(); + + /// delete unused columns + void clean_cols(); +}; + +#endif diff --git a/lily/include/pstaff.hh b/lily/include/pstaff.hh new file mode 100644 index 0000000000..50a7f0c719 --- /dev/null +++ b/lily/include/pstaff.hh @@ -0,0 +1,25 @@ +#ifndef PSTAFF_HH +#define PSTAFF_HH + +#include "proto.hh" +#include "plist.hh" +#include "item.hh" +#include "symbol.hh" + +/// items grouped horizontally +struct PStaff { + PScore * pscore_l_; + + + PointerList spans; + PointerList its; + + /* *************** */ + void add(Item*i); + PStaff(PScore*); + +private: + PStaff(PStaff const&); +}; + +#endif diff --git a/lily/include/qlp.hh b/lily/include/qlp.hh new file mode 100644 index 0000000000..ccfba72bb8 --- /dev/null +++ b/lily/include/qlp.hh @@ -0,0 +1,97 @@ +/* + qlp.hh -- declare Ineq_constrained_qp, Mixed_qp + + source file of the LilyPond music typesetter + + (c) 1997 Han-Wen Nienhuys +*/ + +#ifndef QLP_HH +#define QLP_HH + +#include "matrix.hh" + +/// inequality constrained quadratic program +class Ineq_constrained_qp { + friend class Active_constraints; + + Array cons; + Array consrhs; +public: + Matrix quad; + Vector lin; + Real const_term; + + + /** + use a KKT method to assert optimality of sol + */ + void assert_solution(Vector sol) const; + /// solve the problem using a projected gradient method + Vector solve(Vector start) const; + + /** + @return the number of variables in the problem + */ + int dim() const{ + return lin.dim(); + } + + /** + add a constraint + + + c*vars >= r + + PRE + c.dim() == dim(); + + */ + void add_inequality_cons(Vector c, double r); + + /** set up matrices to go with the problem. */ + Ineq_constrained_qp(int novars); + + /** + evaluate the quadratic function for input #v# + */ + Real eval(Vector v); + + void eliminate_var(int idx, Real value); + void OK()const; + void print() const; + +}; + + +/** + Quadratic programming with mixed linear constraints. + problem definition of a quadratic optimisation problem with linear + inequality and equality constraints + + + x^T QUAD x /2 + b^T x +*/ +class Mixed_qp :public Ineq_constrained_qp { + Array eq_cons; + Array eq_consrhs; +public: + Mixed_qp(int n); + void OK() const; + void print() const; + + Vector solve(Vector start) const; + void add_fixed_var(int i , Real value); + + + /** + add a constraint, + + c*vars == r + + PRE + c.dim()==dim(); + */ + void add_equality_cons(Vector c, double r); +}; +#endif diff --git a/lily/include/qlpsolve.hh b/lily/include/qlpsolve.hh new file mode 100644 index 0000000000..7c9b8da341 --- /dev/null +++ b/lily/include/qlpsolve.hh @@ -0,0 +1,91 @@ +/* + qlpsolve.hh -- declare Active_constraints, Inactive_iter + + source file of the LilyPond music typesetter + + (c) 1997 Han-Wen Nienhuys +*/ + + +#ifndef QLPSOLVE_HH +#define QLPSOLVE_HH +#include "qlp.hh" +#include "matrix.hh" + + +/** + This class represents the set of active (binding) constraints + which can be active while the QLP algorithm is in a feasible + point. The active constraints are numbered. + If the constraints are of the form + + A^T*x >= b + + then the binding constraints are those where the >= is equality. + + */ + +class Active_constraints { + friend class Inactive_iter; + + + Matrix A,H; + Array active; + Array inactive; // actually this is a set, not an array. + const Ineq_constrained_qp *opt; + +public: + String status()const; + + Vector vec(int k) const { return opt->cons[k]; } + Real rhs(int k) const { return opt->consrhs[k]; } + + + /** drop constraint. drop constraint k from the active set. k is the index of the + constraint in #active# + + */ + void drop (int k); + + + /** add constraint j. + add constraint j to the active set j is the index of the + constraint in #inactive# + */ + void add(int j); + + /// exchange in and out. + void exchange(int in, int out) { add(in); drop (out); } + + + Vector find_active_optimum(Vector g); + + /// get lagrange multipliers. + Vector get_lagrange(Vector v); + + Active_constraints(Ineq_constrained_qp const *op); + /** construct: no constraints active, n vars. Put the equalities + into the constraints. */ + + /// check invariants + void OK(); +}; + + +/** + loop through the inactive constraints. + */ +class Inactive_iter { + int j; + Active_constraints const* ac; +public: + Inactive_iter(Active_constraints const &c) { ac=&c; j=0; } + int idx() const { return j; } + void operator ++(int) { j++; } + int constraint_id() const { return ac->inactive[j]; } + Vector vec() const { return ac->vec(constraint_id()); } + Real rhs() const { return ac->rhs(constraint_id()); } + bool ok() const { return j < ac->inactive.size(); } +}; + +#endif // QLPSOLVE_HH diff --git a/lily/include/register.hh b/lily/include/register.hh new file mode 100644 index 0000000000..da80db38fe --- /dev/null +++ b/lily/include/register.hh @@ -0,0 +1,107 @@ +/* + register.hh -- part of LilyPond + + (c) 1996,1997 Han-Wen Nienhuys +*/ + +#ifndef REGISTER_HH +#define REGISTER_HH + +#include "proto.hh" +#include "varray.hh" +#include "request.hh" +#include "staff-elem-info.hh" + +/** + a struct which processes requests, and creates the #Staff_elem#s. + It may use derived classes. Hungarian postfix: register + */ +class Request_register { + friend class Register_group_register; + /** + You cannot copy a Request_register + */ + Request_register(const Request_register&){} +protected: + + /// utility + virtual Paper_def * paper() const; + + /** + try to fit the request in this register + + @return + false: not noted, not taken. + + true: request swallowed. Don't try to put the request elsewhere. + + + Default: always return false + */ + virtual bool try_request(Request *req_l); + + /// make items/spanners with the requests you got + virtual void process_requests(){} + + /** typeset any items/spanners. Default: do nothing + */ + virtual void pre_move_processing(){} + /** reset any appropriate data. Default: do nothing + */ + virtual void post_move_processing(){} + + /** + Is this request eligible to be processed? Default: return false. + */ + virtual bool acceptable_request_b(Request*) const; + + /** + typeset a "command" item. Default: pass on to daddy. + If the column is not breakable, #pre_p# and #post_p# are junked + */ + virtual void typeset_breakable_item(Item * pre_p , + Item * nobreak_p, Item * post_p); + /** + Invoke walker method to typeset element. Default: pass on to daddy. + */ + virtual void typeset_element(Staff_elem*elem_p); + + /** + take note of item/spanner + put item in spanner. Adjust local key; etc. + + Default: ignore the info + */ + virtual void acknowledge_element(Staff_elem_info) {} + /** + Announce element. Default: pass on to daddy. Utility + */ + virtual void announce_element(Staff_elem_info); + /** + Set features of the register(s). Default: ignore features. + */ + virtual void set_feature(Features){} + /** + Does this equal or contain a certain register? + */ + virtual bool contains_b(Request_register*reg_l); + /** + Get information on the staff. Default: ask daddy. + */ + virtual Staff_info get_staff_info(); + + virtual void do_print()const; +public: + /** Every Request_register (except for the 'top' which is directly + inside the Staff_walker, is a element of a group. */ + Register_group_register * daddy_reg_l_; + + Request_register(); + virtual ~Request_register(){} + NAME_MEMBERS(Request_register); + void print() const; +}; + + +#endif // REGISTER_HH + diff --git a/lily/include/registergroup.hh b/lily/include/registergroup.hh new file mode 100644 index 0000000000..6d6e76a15b --- /dev/null +++ b/lily/include/registergroup.hh @@ -0,0 +1,54 @@ +/* + registergroup.hh -- declare + + source file of the LilyPond music typesetter + + (c) 1997 Han-Wen Nienhuys +*/ + + +#ifndef REGISTERGROUP_HH +#define REGISTERGROUP_HH + + +#include "plist.hh" +#include "staff-elem-info.hh" +#include "register.hh" + +/** + Group a number of registers. Usually delegates everything to its contents. + Postfix: group + */ +class Register_group_register : public Request_register { +protected: + IPointerList reg_list_; + virtual void do_print()const; +public: + + /** + Junk #reg_l#. + + Pre: + #reg_l# is in #reg_list_# + */ + virtual void terminate_register(Request_register * reg_l); + + /** + Remove #reg_l# from the list, and return it. + */ + Request_register * get_register_p(Request_register*reg_l); + virtual void set_feature(Features i); + virtual bool acceptable_request_b(Request*); + virtual void pre_move_processing(); + virtual void post_move_processing(); + virtual void acknowledge_element(Staff_elem_info info); + virtual bool try_request(Request*); + virtual void process_requests(); + virtual ~Register_group_register(); + virtual void add(Request_register* reg_p); + virtual bool contains_b(Request_register*); +}; + +#endif // REGISTERGROUP_HH + + diff --git a/lily/include/reqtodo.hh b/lily/include/reqtodo.hh new file mode 100644 index 0000000000..eaed606453 --- /dev/null +++ b/lily/include/reqtodo.hh @@ -0,0 +1,83 @@ +#if 0 + + + +/**Draw a (Guitar) chord above or below this ``note''. +Why a request? +Because everything else is done in requests. +*/ +struct Chord : Request { + // don't know how this looks. +}; + + +/// for absolute dynamics +enum Loudness { + FFF, FF, F, MF, MP, P, PP, PPP +} ; + + +/** +Start/stop a bracket at this note. if #nplet# is set, the staff will +try to put an appropriate number over the bracket +*/ +struct Bracket_req : Span_req { + int nplet; // print a number over the beam. +}; + +struct Subtle_req { + Moment subtime; +}; + + +/** helper in the hierarchy. Each dynamic is bound to one note ( a + crescendo spanning multiple notes is thought to be made of two + "dynamics": a start and a stop). Dynamic changes can occur in a + smaller time than the length of its note, therefore fore each + Dynamic request carries a time, measured from the start of its + note. + + This subfield would come in handy, if mpp96 was adapted for midi + support. + + Dynamic should have been derived from request, but I don't want to + fuss with virtual baseclasses. */ + +struct Dynamic:Subtle_req { + +}; +/// do a crescendo +struct Cresc_req : Span_req, Dynamic { + +}; + +/// do a decrescendo +struct Decresc_req : Span_req, Dynamic { + +}; + +/// do a dynamic like "fff" or "mp" +struct Absdynamic_req : Request, Dynamic { + Loudness loudness; +}; + +struct Grace_req : Subtle_req { + +}; + +struct Grace_turn_req : Grace_turn { + +}; + +struct Grace_note : Melodic_req { + +}; + +struct Grace_notes { + +}; + +struct Glissando_req : Span_req { + +}; +#endif diff --git a/lily/include/request.hh b/lily/include/request.hh new file mode 100644 index 0000000000..1936d5a2ab --- /dev/null +++ b/lily/include/request.hh @@ -0,0 +1,73 @@ +/* + request.hh -- declare Request baseclasses. + + source file of the LilyPond music typesetter + + (c) 1997 Han-Wen Nienhuys +*/ + +#ifndef REQUEST_HH +#define REQUEST_HH +// LilyPond's second egg of columbus! + +#include "glob.hh" +#include "string.hh" +#include "moment.hh" +#include "class-name.hh" + +/** + a voice element wants something printed. + Hungarian postfix: req + @see lilygut manpage + */ +class Request { +public: + Voice_element*elt_l_; + char const* defined_ch_c_l_; + + /* *************** */ + Voice * voice_l(); + Request(); + Request(Request const&); + virtual ~Request(){} + + NAME_MEMBERS(Request); + virtual Request* clone() const { return new Request(*this); } + void print()const ; + + virtual Moment duration() const { return 0; } + + /* accessors for children + maybe checkout RTTI + */ + virtual Barcheck_req *barcheck() { return 0; } + virtual Note_req *note() { return 0;} + virtual Script_req *script() { return 0;} + virtual Stem_req *stem() { return 0;} + virtual Text_req*text() { return 0; } + virtual Rest_req *rest() { return 0; } + virtual Span_req *span() { return 0; } + virtual Beam_req *beam() { return 0 ; } + virtual Plet_req* plet() { return 0; } + virtual Slur_req *slur() { return 0 ; } + virtual Rhythmic_req*rhythmic() { return 0; } + virtual Lyric_req* lreq_l() { return 0; } + virtual Melodic_req *melodic() { return 0; } + virtual Terminate_voice_req *terminate() {return 0;} + virtual Group_change_req * groupchange() { return 0;} + virtual Group_feature_req * groupfeature() { return 0; } + virtual Spacing_req * spacing() { return 0; } + virtual Blank_req * blank() { return 0; } + virtual Musical_req *musical() { return 0; } + virtual Command_req * command() { return 0; } +protected: + virtual void do_print()const ; +}; + +#define REQUESTMETHODS(T,accessor) \ +virtual T * accessor() { return this;}\ +NAME_MEMBERS(T);\ +virtual Request *clone() const { return new T(*this); } \ +virtual void do_print() const + +#endif diff --git a/lily/include/rest.hh b/lily/include/rest.hh new file mode 100644 index 0000000000..85c7266677 --- /dev/null +++ b/lily/include/rest.hh @@ -0,0 +1,25 @@ +/* + rest.hh -- part of LilyPond + + (c) 1996,97 Han-Wen Nienhuys +*/ + +#ifndef REST_HH +#define REST_HH +#include "item.hh" + +struct Rest : Item { + + int dots; + int balltype; + + /* *************** */ + + + Rest(int dur,int dots); + void do_print()const; +NAME_MEMBERS(Rest); + Molecule* brew_molecule_p()const; +}; +#endif + diff --git a/lily/include/score-column.hh b/lily/include/score-column.hh new file mode 100644 index 0000000000..e961d04920 --- /dev/null +++ b/lily/include/score-column.hh @@ -0,0 +1,59 @@ +/* + sccol.hh -- part of LilyPond + + (c) 1996,97 Han-Wen Nienhuys +*/ + +#ifndef SCCOL_HH +#define SCCOL_HH +#include "proto.hh" +#include "varray.hh" +#include "moment.hh" + + +/** + + When typesetting hasn't started on PScore yet, the columns which + contain data have a rhythmical position. Score_column is the type + with a rhythmical time attached to it. The calculation of + idealspacing is done with data in these columns. (notably: the + #durations# field) + + */ + +class Score_column { + friend class Score; + friend class Score_walker; + + bool musical_b_; + Moment when_; + void set_breakable(); +public: + /// indirection to column + PCol * pcol_l_; + + /// length of notes/rests in this column + Array durations; + + /* *************** */ + + Moment when() { return when_; } + Score_column(Moment when); + static int compare(Score_column & c1, Score_column &c2); + void add_duration(Moment ); + void preprocess(); + bool breakable_b(); + bool musical_b() { return musical_b_; } + bool used_b(); + void print() const; + + +}; + +instantiate_compare(Score_column&, Score_column::compare); + +#endif // SCCOL_HH + + + + diff --git a/lily/include/score-walker.hh b/lily/include/score-walker.hh new file mode 100644 index 0000000000..b3d304256e --- /dev/null +++ b/lily/include/score-walker.hh @@ -0,0 +1,37 @@ +/* + score-walker.hh -- declare Score_walker + + source file of the LilyPond music typesetter + + (c) 1997 Han-Wen Nienhuys +*/ + + +#ifndef SCOREWALKER_HH +#define SCOREWALKER_HH +#include "pcursor.hh" +#include "proto.hh" +#include "varray.hh" + + +/** + walk through the score_columns, and while doing so, walk all staffs in a score. + */ +class Score_walker : public PCursor +{ + Score* score_l_; + /// walkers for the individual staves. + Array walker_p_arr_; + Array disallow_break_walk_l_arr; + int disallow_break_count_; + void reinit(); +public: + void allow_break(Staff_walker*w); + Score_walker(Score*); + ~Score_walker(); + Moment when(); + void operator++(int); + /// process staff walkers. + void process(); +}; +#endif // SCOREWALKER_HH diff --git a/lily/include/score.hh b/lily/include/score.hh new file mode 100644 index 0000000000..a865ed02f3 --- /dev/null +++ b/lily/include/score.hh @@ -0,0 +1,90 @@ +/* + score.hh -- declare Score + + source file of the LilyPond music typesetter + + (c) 1997 Han-Wen Nienhuys +*/ + + +#ifndef SCORE_HH +#define SCORE_HH + +#include "varray.hh" +#include "proto.hh" +#include "plist.hh" +#include "moment.hh" +#include "assoc.hh" +#include "string.hh" + +/// the total music def of one movement +struct Score { + /// paper_, staffs_ and commands_ form the problem definition. + Paper_def *paper_p_; + Midi_def *midi_p_; + IPointerList staffs_; + + /// "runtime" fields for setting up spacing + IPointerList cols_; + PScore *pscore_p_; + + const char *defined_ch_c_l_; + int errorlevel_i_; + + /* *************************************************************** */ + + /// construction + Score(); + ~Score(); + void add(Staff*); + + /// do everything except outputting to file + void process(); + + /// output to file + void output(String fn); + + + /// + void set(Midi_def* midi_p); + /// + void set(Paper_def* midi_p); + + // standard + void OK() const; + void print() const; + + /// find a column. + PCursor find_col(Moment,bool); + + /// when does the last *musical* element finish? + Moment last() const; + +private: + void paper_output(); + void setup_music(); + void process_music(); + /// do midi stuff + void midi(); + + /// do paper stuff + void paper(); + + // utils: + PCursor create_cols(Moment); + + Score(Score const&){} + + /** + make the pcol_l_ fields of each Score_column point to the correct PCol, + remove any unnecessary Score_column's + */ + void do_cols(); + + /// remove unused cols + void clean_cols(); + + /// add #Idealspacings# to #pscore_# + void calc_idealspacing(); +}; +#endif diff --git a/lily/include/scoreline.hh b/lily/include/scoreline.hh new file mode 100644 index 0000000000..f4e1987033 --- /dev/null +++ b/lily/include/scoreline.hh @@ -0,0 +1,33 @@ +/* + scoreline.hh -- part of LilyPond + + (c) 1996,97 Han-Wen Nienhuys +*/ + +#ifndef SCORELINE_HH +#define SCORELINE_HH +#include "proto.hh" +#include "plist.hh" +#include "varray.hh" + +/// the columns of a score that form one line. +struct +Line_of_score { + PointerList cols; + + // need to store height of each staff. + IPointerList staffs; + PScore * pscore_l_; // needed to generate staffs + + /* *************** */ + void process() ; + Line_of_score(Array sv, PScore *); + + String TeXstring() const; + + // is #c# contained in #*this#? + bool element(const PCol *c); +}; + +#endif + diff --git a/lily/include/script-def.hh b/lily/include/script-def.hh new file mode 100644 index 0000000000..8b5be32561 --- /dev/null +++ b/lily/include/script-def.hh @@ -0,0 +1,25 @@ +/* + script-def.hh -- part of LilyPond + + (c) 1996,97 Han-Wen Nienhuys +*/ + +#ifndef SCRIPTDEF_HH +#define SCRIPTDEF_HH +#include "string.hh" +struct Script_def{ + int stemdir; + int staffdir; + + bool invertsym; + String symidx; + + /* *************** */ + int compare(Script_def const &); + void print() const; + Script_def(String, int, int ,bool); +}; + + +#endif // SCRIPTDEF_HH + diff --git a/lily/include/script-reg.hh b/lily/include/script-reg.hh new file mode 100644 index 0000000000..33592cae03 --- /dev/null +++ b/lily/include/script-reg.hh @@ -0,0 +1,29 @@ +/* + script-reg.hh -- part of LilyPond + + (c) 1997 Han-Wen Nienhuys +*/ + + +#ifndef SCRIPTREG_HH +#define SCRIPTREG_HH + +#include "register.hh" + + +struct Script_register : Request_register { + Script * script_p_; + Script_req * script_req_l_; + int dir_i_; + /* *************** */ + void set_feature(Features dir_i_); + Script_register(); + virtual bool try_request(Request*); + virtual void process_requests(); + virtual void acknowledge_element(Staff_elem_info); + virtual void pre_move_processing(); + virtual void post_move_processing(); + NAME_MEMBERS(Script_register); +}; + +#endif // SCRIPTREG_HH diff --git a/lily/include/script.hh b/lily/include/script.hh new file mode 100644 index 0000000000..df408f0435 --- /dev/null +++ b/lily/include/script.hh @@ -0,0 +1,41 @@ +/* + script.hh -- part of LilyPond + + (c) 1996,97 Han-Wen Nienhuys +*/ + +#ifndef SCRIPT_HH +#define SCRIPT_HH + +#include "script-def.hh" +#include "item.hh" + +struct Script : Item { + int dir; + int symdir; + int pos; + int staffsize; + Script_def *specs_l_; + Stem *stem_l_; + Array support; + + /* *************** */ + NAME_MEMBERS(Script); + Molecule *brew_molecule_p()const; + virtual void do_post_processing(); + virtual void do_pre_processing(); + Script(Script_req*, int staffsize); + void set_support(Item*); + void set_stem(Stem*); + Interval support_height()const; + virtual Interval width() const; +private: + void set_symdir(); + void set_default_dir(); + void set_default_index(); + Symbol symbol()const; +}; + + +#endif // SCRIPT_HH + diff --git a/lily/include/slur-reg.hh b/lily/include/slur-reg.hh new file mode 100644 index 0000000000..e357c8795e --- /dev/null +++ b/lily/include/slur-reg.hh @@ -0,0 +1,33 @@ +/* + slur-reg.hh -- declare Slur_register + + (c) 1997 Han-Wen Nienhuys +*/ + + +#ifndef SLURREG_HH +#define SLURREG_HH + +#include "register.hh" + +struct Slur_register : Request_register { + Array requests_arr_; + Array new_slur_req_l_arr_; + Array slur_l_stack_; + Array end_slur_l_arr_; + + int dir_i_; + + /* *************** */ + ~Slur_register(); + Slur_register(); + virtual bool try_request(Request*); + virtual void process_requests(); + virtual void acknowledge_element(Staff_elem_info); + virtual void pre_move_processing(); + virtual void post_move_processing(); + virtual void set_feature(Features); + NAME_MEMBERS(Slur_register); +}; + +#endif // SLURREG_HH diff --git a/lily/include/slur.hh b/lily/include/slur.hh new file mode 100644 index 0000000000..87f1fe855e --- /dev/null +++ b/lily/include/slur.hh @@ -0,0 +1,37 @@ +/* + slur.hh -- part of LilyPond + + (c) 1996,97 Han-Wen Nienhuys +*/ + +#ifndef SLUR_HH +#define SLUR_HH + +#include "directional-spanner.hh" +#include "fproto.hh" +#include "varray.hh" + +struct Slur : Directional_spanner { + + Array encompass; + + bool open_left, open_right; + + /* *************** */ + Offset center() const; + Slur(); + void do_post_processing(); + void do_pre_processing(); + void add(Notehead*); + void set_default_dir(); + + Spanner* do_break_at( PCol*, PCol*) const; + void process(); +private: + Molecule*brew_molecule_p()const; + NAME_MEMBERS(Slur); +}; + +#endif // SLUR_HH + + diff --git a/lily/include/spanner.hh b/lily/include/spanner.hh new file mode 100644 index 0000000000..43a3567fa5 --- /dev/null +++ b/lily/include/spanner.hh @@ -0,0 +1,54 @@ +/* + spanner.hh -- part of LilyPond + + (c) 1996,97 Han-Wen Nienhuys +*/ + +#ifndef SPANNER_HH +#define SPANNER_HH + +#include "proto.hh" +#include "staff-elem.hh" + + +/** a symbol which is attached between two columns. A spanner is a symbol which spans across several columns, so its + final appearance can only be calculated after the breaking problem + is solved. + + Examples + + - (de)crescendo + - slur + - beam + - bracket + + + Spanner should know about the items which it should consider: + e.g. slurs should be steep enough to "enclose" all those items. This + is absolutely necessary for beams, since they have to adjust the + length of stems of notes they encompass. + + */ +struct Spanner:Staff_elem { + PCol *left, *right; + + + /* *************** */ + + Spanner(); + virtual Interval width()const; + void do_print()const; + + Spanner *broken_at(PCol *c1, PCol *c2) const; + virtual Spanner* spanner() { return this; } +protected: + + /** + clone a piece of this spanner. + PRE + c1 >= start, c2 <= stop + */ + virtual Spanner *do_break_at( PCol *c1, PCol *c2) const=0; + NAME_MEMBERS(Spanner); +}; +#endif diff --git a/lily/include/staff-column.hh b/lily/include/staff-column.hh new file mode 100644 index 0000000000..dd6303ea8c --- /dev/null +++ b/lily/include/staff-column.hh @@ -0,0 +1,48 @@ +/* + staff-column.hh -- declare Staff_column + + (c) 1996,97 Han-Wen Nienhuys +*/ + +#ifndef STAFFCOLUMN_HH +#define STAFFCOLUMN_HH +#include "proto.hh" +#include "varray.hh" +#include "moment.hh" + +/// store simultaneous requests +class Staff_column { + + Staff_column(Staff_column const&); + +public: + Array creationreq_l_arr_; + Array musicalreq_l_arr_; + Array commandreq_l_arr_; + Staff * staff_l_; + + /// fields to collect timing data vertically. + Array timing_req_l_arr_; + Score_column *musical_column_l_, *command_column_l_; + + /* *************** */ + + Staff_column(); + + Moment when() const; + void set_cols(Score_column *c1, Score_column *c2); + void add(Voice_element*ve); + void OK() const; + ~Staff_column(); + void typeset_breakable_items(Array &pre_p_arr, + Array &nobreak_p_arr, + Array &post_p_arr); + void typeset_musical_item(Item *i); +protected: + void setup_one_request(Request*); +}; + + + +#endif // STAFFCOLUMN_HH + diff --git a/lily/include/staff-elem-info.hh b/lily/include/staff-elem-info.hh new file mode 100644 index 0000000000..9c6264a86b --- /dev/null +++ b/lily/include/staff-elem-info.hh @@ -0,0 +1,43 @@ +/* + staff-elem-info.hh -- declare Staff_elem_info + + source file of the LilyPond music typesetter + + (c) 1997 Han-Wen Nienhuys +*/ + + +#ifndef STAFFELEMINFO_HH +#define STAFFELEMINFO_HH + +#include "proto.hh" +#include "varray.hh" +/// data container. +struct Staff_elem_info { + Staff_elem * elem_p_; + Request*req_l_; + const Voice * voice_l_; + Array origin_reg_l_arr_; + + + /* *** */ + Staff_elem_info(Staff_elem*, Request*); + Staff_elem_info(); +}; + +struct Staff_info { + int *c0_position_i_; + Staff_walker *walk_l_; + const Time_description *time_c_l_; + const Rhythmic_grouping *rhythmic_c_l_; +}; + + +struct Features { + bool initialiser_b_; + int direction_i_; + + Features(); + static Features dir(int); +}; +#endif // STAFFELEMINFO_HH diff --git a/lily/include/staff-elem.hh b/lily/include/staff-elem.hh new file mode 100644 index 0000000000..e2fce84582 --- /dev/null +++ b/lily/include/staff-elem.hh @@ -0,0 +1,88 @@ +/* + staff-elem.hh -- part of LilyPond + + (c) 1996,97 Han-Wen Nienhuys +*/ + +#ifndef STAFFELEM_HH +#define STAFFELEM_HH +#include "varray.hh" +#include "proto.hh" +#include "offset.hh" +#include "molecule.hh" +#include "class-name.hh" + + +/** Both Spanner and Item are Staff_elem's. Most Staff_elem's depend + on other Staff_elem's, eg, Beam needs to know and set direction of + Stem. So the Beam has to be calculated *before* Stem. This is + accomplished with the dependencies field of struct Staff_elem. + + */ +struct Staff_elem { + enum Status { + ORPHAN, // not yet added to pstaff + VIRGIN, // added to pstaff + PRECALCING, + PRECALCED, // calcs before spacing done + POSTCALCING, + POSTCALCED, // after spacing calcs done + OUTPUT, // molecule has been output + } status; + + /// the pstaff it is in + PStaff *pstaff_l_; + + /* *************** */ + Staff_elem(Staff_elem const&); + String TeXstring () const ; + virtual void print() const; + virtual Interval width() const; + virtual Interval height() const; + Paper_def *paper() const; + virtual ~Staff_elem(); + Staff_elem(); + NAME_MEMBERS(Staff_elem); + void translate(Offset); + void add_processing(); + void pre_processing(); + void post_processing(); + void molecule_processing(); + + virtual Spanner* spanner() { return 0; } + virtual Item * item() { return 0; } + void add_dependency(Staff_elem* ); + void substitute_dependency(Staff_elem* old, Staff_elem * newdep); + +protected: + + /// do printing of derived info. + virtual void do_print() const=0; + /// generate the molecule + virtual Molecule* brew_molecule_p()const=0; + ///executed directly after the item is added to the PScore + virtual void do_add_processing(); + /// do calculations before determining horizontal spacing + virtual void do_pre_processing(); + + /// do calculations after determining horizontal spacing + virtual void do_post_processing(); + + Array dependants; + +private: + /// member: the symbols + Molecule *output; // should scrap, and use temp var? + + + /** + This is needed, because #output# may still be + NULL. + */ + Offset offset_; + Array dependencies; +}; + + +#endif // STAFFELEM_HH + diff --git a/lily/include/staff-walker.hh b/lily/include/staff-walker.hh new file mode 100644 index 0000000000..fb0d098e07 --- /dev/null +++ b/lily/include/staff-walker.hh @@ -0,0 +1,47 @@ +/* + staff-walker.hh -- declare Staff_walker + + (c) 1996,97 Han-Wen Nienhuys +*/ + +#ifndef STAFFWALKER_HH +#define STAFFWALKER_HH + +#include "proto.hh" +#include "time-description.hh" +#include "pcursor.hh" + +/** + manage run-time info when walking staffcolumns such as: key, + meter, pending beams & slurs + */ +struct Staff_walker : public PCursor { + Staff * staff_l_; + PScore * pscore_l_; + Score_walker *score_walk_l_; + Time_description time_; + Rhythmic_grouping *default_grouping; + + /* *************** */ + + Moment when() const; + virtual ~Staff_walker(); + Staff_walker(Staff*, PScore*); + void process() ; + + void operator++(int); + void allow_break(); + +protected: + /// every time before ++ is called + virtual void do_pre_move(){} + /// every time after ++ is called + virtual void do_post_move(){} + virtual void process_requests()=0; +private: + void process_timing_reqs(); + Staff_walker(Staff_walker const&); +}; + +#endif // STAFFWALKER_HH + diff --git a/lily/include/staff.hh b/lily/include/staff.hh new file mode 100644 index 0000000000..959859b6e4 --- /dev/null +++ b/lily/include/staff.hh @@ -0,0 +1,61 @@ +/* + staff.hh -- declare Staff + + source file of the LilyPond music typesetter + + (c) 1997 Han-Wen Nienhuys +*/ + +#ifndef STAFF_HH +#define STAFF_HH + +#include "plist.hh" +#include "proto.hh" +#include "moment.hh" + +/// base class for a collection of voices. +class Staff { + Staff(const Staff&src); + + /// synchronous horizontal stuff + IPointerList voice_list_; + Staff_column *get_col(Moment, PCursor * last= 0); + +public: + + /// runtime field + IPointerList cols_; + + Score *score_l_; + PScore *pscore_l_; + PStaff *pstaff_l_; + + /* *************************************************************** */ + + void add(const PointerList &s); + + void add_voice(Voice *v); + Paper_def*paper()const; + + void setup_staffcols(); + + void OK() const; + void print() const; + + /// when does the last *musical* element finish? + Moment last() const; + +// /// extract midi info +// Midi_track* midi_track_p(); + + /// remove unused cols + void clean_cols() ; + Staff(); + + virtual void set_output(PScore * destination)=0; + virtual Staff_walker *get_walker_p()=0; + virtual ~Staff() { } +protected: + +}; +#endif diff --git a/lily/include/staffelem.hh b/lily/include/staffelem.hh new file mode 100644 index 0000000000..3928c994e9 --- /dev/null +++ b/lily/include/staffelem.hh @@ -0,0 +1,84 @@ +/* + staffelem.hh -- part of LilyPond + + (c) 1996,97 Han-Wen Nienhuys +*/ + +#ifndef STAFFELEM_HH +#define STAFFELEM_HH +#include "varray.hh" +#include "proto.hh" +#include "offset.hh" +#include "molecule.hh" + +/** Both Spanner and Item are Staff_elem's. Most Staff_elem's depend + on other Staff_elem's, eg, Beam needs to know and set direction of + Stem. So the Beam has to be calculated *before* Stem. This is + accomplished with the dependencies field of struct Staff_elem. + + */ +struct Staff_elem { + enum Status { + ORPHAN, // not yet added to pstaff + VIRGIN, // added to pstaff + PRECALCING, + PRECALCED, // calcs before spacing done + POSTCALCING, + POSTCALCED, // after spacing calcs done + OUTPUT, // molecule has been output + } status; + + /// the pstaff it is in + PStaff *pstaff_l_; + + /* *************** */ + Staff_elem(Staff_elem const&); + String TeXstring () const ; + virtual void print() const; + virtual Interval width() const; + virtual Interval height() const; + Paperdef *paper() const; + virtual ~Staff_elem(); + Staff_elem(); + + void translate(Offset); + void add_processing(); + void pre_processing(); + void post_processing(); + void molecule_processing(); + virtual const char *name() const; // to find out derived classes. + virtual Spanner* spanner() { return 0; } + virtual Item * item() { return 0; } + void add_depedency(Staff_elem* ); + void substitute_dependency(Staff_elem* old, Staff_elem * newdep); +protected: + + /// do printing of derived info. + virtual void do_print() const=0; + /// generate the molecule + virtual Molecule* brew_molecule_p()const=0; + ///executed directly after the item is added to the PScore + virtual void do_add_processing(); + /// do calculations before determining horizontal spacing + virtual void do_pre_processing(); + + /// do calculations after determining horizontal spacing + virtual void do_post_processing(); + + Array dependants; + +private: + /// member: the symbols + Molecule *output; // should scrap, and use temp var? + + + /** + This is needed, because #output# may still be + NULL. + */ + Offset offset_; + Array dependencies; +}; +#define NAME_METHOD(c) const char *c::name()const{ return #c; } struct c +#endif // STAFFELEM_HH + diff --git a/lily/include/staffeleminfo.hh b/lily/include/staffeleminfo.hh new file mode 100644 index 0000000000..b8af8aeb22 --- /dev/null +++ b/lily/include/staffeleminfo.hh @@ -0,0 +1,28 @@ +/* + staffeleminfo.hh -- declare Staff_elem_info + + source file of the LilyPond music typesetter + + (c) 1997 Han-Wen Nienhuys +*/ + + +#ifndef STAFFELEMINFO_HH +#define STAFFELEMINFO_HH + +#include "proto.hh" + +/// data container. +struct Staff_elem_info { + Staff_elem * elem_p_; + Request*req_l_; + const Voice * voice_l_; + Voice_group_registers * group_regs_l_; + Request_register * origin_reg_l_; + + /* *** */ + Staff_elem_info(Staff_elem*, Request*, Request_register*); + Staff_elem_info(); +}; + +#endif // STAFFELEMINFO_HH diff --git a/lily/include/staffline.hh b/lily/include/staffline.hh new file mode 100644 index 0000000000..9fbe3ec917 --- /dev/null +++ b/lily/include/staffline.hh @@ -0,0 +1,31 @@ +/* + staffline.hh -- horizontal structures for broken scores. + + (c) 1996,97 Han-Wen Nienhuys +*/ + +#ifndef STAFFLINE_HH +#define STAFFLINE_HH + +#include "proto.hh" +#include "real.hh" +#include "plist.hh" +#include "varray.hh" +#include "glob.hh" +#include "pstaff.hh" + +/// one broken line of staff. +struct Line_of_staff { + + Line_of_score * line_of_score_l_; + PStaff *pstaff_l_; + + /* *************** */ + + String TeXstring() const; + Line_of_staff(Line_of_score*, PStaff *); + Interval height() const; + void process(); +}; + +#endif diff --git a/lily/include/staffsym.hh b/lily/include/staffsym.hh new file mode 100644 index 0000000000..bcec2bfaff --- /dev/null +++ b/lily/include/staffsym.hh @@ -0,0 +1,30 @@ +/* + staffsym.hh -- declare Staff_symbol + + source file of the LilyPond music typesetter + + (c) 1997 Han-Wen Nienhuys +*/ + + +#ifndef STAFFSYM_HH +#define STAFFSYM_HH +#include "spanner.hh" +/** + This spanner draws the lines of a pstaff. + The bottom line is position 0. + */ +class Staff_symbol : public Spanner +{ +public: + /// this many lines. + int no_lines_i_; + + NAME_MEMBERS(Staff_symbol); + Staff_symbol(int lines); + virtual Molecule* brew_molecule_p() const; + void set_extent(PCol* p1, PCol* p2); + virtual void do_print()const; + virtual Spanner *do_break_at( PCol *c1, PCol *c2) const; +}; +#endif // STAFFSYM_HH diff --git a/lily/include/stem-beam-reg.hh b/lily/include/stem-beam-reg.hh new file mode 100644 index 0000000000..dddba269a4 --- /dev/null +++ b/lily/include/stem-beam-reg.hh @@ -0,0 +1,33 @@ +/* + stem-beam-reg.hh -- part of LilyPond + + (c) 1997 Han-Wen Nienhuys +*/ + + +#ifndef STEMBEAMREG_HH +#define STEMBEAMREG_HH +#include "register.hh" + +struct Stem_beam_register : Request_register { + Stem * stem_p_; + Beam * beam_p_; + Beam_req * beam_req_l_; + Stem_req * stem_req_l_; + Beam_req * start_req_l_; + bool end_beam_b_; + Rhythmic_grouping *current_grouping; + int default_dir_i_; + + /* *************** */ + Stem_beam_register(); + ~Stem_beam_register(); + virtual void set_feature(Features dir_i_); + virtual bool try_request(Request*); + virtual void process_requests(); + virtual void acknowledge_element(Staff_elem_info); + virtual void pre_move_processing(); + virtual void post_move_processing(); + NAME_MEMBERS(Stem_beam_register); +}; +#endif // STEMBEAMREG_HH diff --git a/lily/include/stem.hh b/lily/include/stem.hh new file mode 100644 index 0000000000..34776ea49c --- /dev/null +++ b/lily/include/stem.hh @@ -0,0 +1,81 @@ +/* + stem.hh -- declare Stem + + (c) 1996,97 Han-Wen Nienhuys +*/ + +#ifndef STEM_HH +#define STEM_HH +#include "item.hh" +#include "varray.hh" +#include "moment.hh" + + +/**the rule attached to the ball. + takes care of: + + \begin{itemize} + \item the rule + \item the flag + \item up/down position. + \end{itemize} + */ + +struct Stem : Item { + /// heads that the stem encompasses (positions) + int minnote, maxnote; + + /// false if in beam + bool print_flag; + + int beams_left; + int beams_right; + + /// needed for determining direction/length + int staff_center; + + + /**extent of the stem (positions). + fractional, since Beam has to adapt them. + */ + + Real bot, top; + Real stemlen; + + /// flagtype? 4 none, 8 8th flag, 0 = beam. + int flag; + + + /** + geen gedonder, jij gaat onder. + -1 stem points down, +1: stem points up + */ + + int dir; + Real stem_xoffset; + + Array heads; + + /* *************** */ + Stem(int center); //, Moment duration); + + /// ensure that this Stem also encompasses the Notehead #n# + void add(Notehead*n); + + NAME_MEMBERS(Stem); + + Real hindex()const; + void do_print() const; + void set_stemend(Real); + int get_default_dir(); + void set_default_dir(); + void set_default_stemlen(); + void set_default_extents(); + void set_noteheads(); + void do_pre_processing(); + + Interval width() const; + + Molecule* brew_molecule_p() const; +}; +#endif diff --git a/lily/include/symbol.hh b/lily/include/symbol.hh new file mode 100644 index 0000000000..c166fa5bcf --- /dev/null +++ b/lily/include/symbol.hh @@ -0,0 +1,17 @@ +#ifndef SYMBOL_HH +#define SYMBOL_HH + +#include "string.hh" +#include "boxes.hh" +#include "proto.hh" + +struct Symbol { + String tex; + Box dim; + + Symbol (String, Box); + Symbol(); + String str()const; // for printing. +}; + +#endif diff --git a/lily/include/symtable.hh b/lily/include/symtable.hh new file mode 100644 index 0000000000..f96d02c1ec --- /dev/null +++ b/lily/include/symtable.hh @@ -0,0 +1,28 @@ +/* + lilypond, (c) 1996,97 Han-Wen Nienhuys +*/ +#ifndef SYMTABLE_HH +#define SYMTABLE_HH +#include "assoc.hh" +#include "string.hh" +#include "symbol.hh" + +struct Symtable : public Assoc { + Symbol lookup(String)const; + void print()const; +}; + + +struct Symtables : private Assoc { + + Symtable* operator()(String s); + ~Symtables(); + Symtables(); + Symtables(Symtables const&); + Assoc::add; + void print()const; +}; + + +#endif + diff --git a/lily/include/tex-stream.hh b/lily/include/tex-stream.hh new file mode 100644 index 0000000000..4d5805c556 --- /dev/null +++ b/lily/include/tex-stream.hh @@ -0,0 +1,29 @@ +#ifndef TSTREAM__HH +#define TSTREAM__HH + +#include +#include "string.hh" + + +/** TeX output. + Use this class for writing to a TeX file. + It counts braces to prevent nesting errors, and + it will add a comment sign before each newline. + */ +struct Tex_stream { + bool outputting_comment; + ostream *os; + int nest_level; + + /// open a file for writing + Tex_stream(String filename); + void header(); + /// delegate conversion to string class. + Tex_stream &operator<<(String); + + /// close the file + ~Tex_stream(); +private: + Tex_stream(Tex_stream const&); +}; +#endif diff --git a/lily/include/tex.hh b/lily/include/tex.hh new file mode 100644 index 0000000000..af45ba7d27 --- /dev/null +++ b/lily/include/tex.hh @@ -0,0 +1,25 @@ +#ifndef TEX_HH +#define TEX_HH + +#include "string.hh" +#include "boxes.hh" +#include "scalar.hh" + +/** parameter substitution in TeXstrings. + this function provides a simple macro mechanism: + + if source == "tex%bla%", then + substitute_args(source, {"X","Y"}) == "texXblaY" + */ +String +substitute_args(String source, Array args); + +/// parameter substitution in TeXstrings +String +substitute_args(String source, Array args); + +/// #h# is in points +String vstrut(Real h); + + +#endif diff --git a/lily/include/text-def.hh b/lily/include/text-def.hh new file mode 100644 index 0000000000..cc9c3c95b3 --- /dev/null +++ b/lily/include/text-def.hh @@ -0,0 +1,29 @@ +/* + text-def.hh -- part of LilyPond + + (c) 1996,97 Han-Wen Nienhuys +*/ + +#ifndef TEXTDEF_HH +#define TEXTDEF_HH + +#include "string.hh" +#include "proto.hh" + +struct Text_def { + int align_i_; + String text_str_; + String style_str_; + char const* defined_ch_c_l_; + + + /* ****************/ + virtual ~Text_def() {}; + bool compare(const Text_def&); + Text_def(); + virtual void print() const; + virtual Atom create_atom(Paper_def*) const; +}; + +#endif // TEXTDEF_HH + diff --git a/lily/include/text-item.hh b/lily/include/text-item.hh new file mode 100644 index 0000000000..ae0b556308 --- /dev/null +++ b/lily/include/text-item.hh @@ -0,0 +1,30 @@ +/* + text.hh -- part of LilyPond + + (c) 1996,97 Han-Wen Nienhuys +*/ + +#ifndef TEXT_ITEM_HH +#define TEXT_ITEM_HH + +#include "text-def.hh" +#include "item.hh" + +struct Text_item : Item { + int pos_i_; + int staffsize_i_; + int dir_i_; + Text_def* tdef_l_; + + /* ***************/ + NAME_MEMBERS(Text_item); + virtual void set_default_index(); + Molecule* brew_molecule_p() const; + void do_pre_processing(); + + Text_item(Text_req*,int); +}; + + +#endif // TEXT_HH + diff --git a/lily/include/text-reg.hh b/lily/include/text-reg.hh new file mode 100644 index 0000000000..59317e5bcd --- /dev/null +++ b/lily/include/text-reg.hh @@ -0,0 +1,26 @@ +/* + text-reg.hh -- part of LilyPond + + (c) 1997 Han-Wen Nienhuys +*/ + + +#ifndef TEXTREG_HH +#define TEXTREG_HH +#include "register.hh" + +struct Text_register : Request_register{ + Text_item * text_p_; + Text_req * text_req_l_; + int dir_i_; + /* *************** */ + virtual void set_feature(Features ); + Text_register(); + virtual bool try_request(Request*); + virtual void process_requests(); + virtual void pre_move_processing(); + virtual void post_move_processing(); + NAME_MEMBERS(Text_register); +}; + +#endif // TEXTREG_HH diff --git a/lily/include/text-spanner.hh b/lily/include/text-spanner.hh new file mode 100644 index 0000000000..dbdea979ad --- /dev/null +++ b/lily/include/text-spanner.hh @@ -0,0 +1,34 @@ +/* + textspanner.hh -- part of LilyPond + + (c) 1996,97 Han-Wen Nienhuys +*/ + +#ifndef TEXTSPANNER_HH +#define TEXTSPANNER_HH + +#include "string.hh" +#include "directional-spanner.hh" +#include "text-def.hh" + +/** a spanner which puts texts on top of other spanners. Use for + triplets, eentweetjes, ottava, etc. */ +struct Text_spanner : Spanner { + Text_def spec; + Offset text_off_; + Directional_spanner*support; + + /* *************** */ + + NAME_MEMBERS(Text_spanner); + virtual void do_pre_processing(); + virtual void do_post_processing(); + virtual Interval height() const ; + virtual Molecule* brew_molecule_p()const; + virtual void do_print() const; + virtual Spanner* do_break_at(PCol*,PCol*)const; + Text_spanner(); + void set_support(Directional_spanner*); +}; +#endif // TEXTSPANNER_HH + diff --git a/lily/include/time-description.hh b/lily/include/time-description.hh new file mode 100644 index 0000000000..7e366ec4c2 --- /dev/null +++ b/lily/include/time-description.hh @@ -0,0 +1,50 @@ +/* + moment.hh -- part of LilyPond + + (c) 1996,97 Han-Wen Nienhuys +*/ + +#ifndef tdes_HH +#define tdes_HH + +#include "moment.hh" + +/// full info on where we are +struct Time_description { + Moment when_; + + /// if true, no bars needed, no reduction of whole_in_measure + bool cadenza_b_; + + /// current measure info + Moment whole_per_measure_; + + /// where am i + Moment whole_in_measure_; + + /// how long is one beat? + Moment one_beat_; + + /// idem + int bars_i_; + + /* *************** */ + void set_cadenza(bool); + void OK() const; + Time_description(); + void add(Moment dt); + String str()const; + void print() const; + void setpartial(Moment p); + Moment barleft(); + void set_meter(int,int); + static int compare (Time_description&, Time_description&); +}; + +#include "compare.hh" + + +instantiate_compare(Time_description&,Time_description::compare); + +#endif // Time_description_HH + diff --git a/lily/include/voice-element.hh b/lily/include/voice-element.hh new file mode 100644 index 0000000000..0c5b6b1328 --- /dev/null +++ b/lily/include/voice-element.hh @@ -0,0 +1,37 @@ +/* + voice-element.hh -- declare Voice_element + + source file of the LilyPond music typesetter + + (c) 1997 Han-Wen Nienhuys +*/ + + +#ifndef VOICE_ELEMENT_HH +#define VOICE_ELEMENT_HH + +#include "proto.hh" +#include "plist.hh" +#include "moment.hh" + +/** one horizontal bit. Voice_element is nothing but a container for + *the requests, */ +struct Voice_element { + Moment duration; + char const* defined_ch_c_l_; + const Voice *voice_l_; + IPointerList reqs; + + /* *************** */ + + Voice_element(); + Voice_element(Voice_element const & src ); + + void add(Request*); + bool find_plet_start_bo(char c, Moment& moment_r); + void print ()const; + void set_default_group(String id); + void set_plet_backwards(Moment& now_moment_r, Moment until_moment, int num_i, int den_i); +}; + +#endif // VOICE-ELEMENT_HH diff --git a/lily/include/voice-group-regs.hh b/lily/include/voice-group-regs.hh new file mode 100644 index 0000000000..7c1b4ed78a --- /dev/null +++ b/lily/include/voice-group-regs.hh @@ -0,0 +1,29 @@ +/* + voice-group-regs.hh -- declare Voice_group_registers + + source file of the LilyPond music typesetter + + (c) 1997 Han-Wen Nienhuys +*/ + + +#ifndef VOICEGROUPREGS_HH +#define VOICEGROUPREGS_HH + +#include "registergroup.hh" + +struct Voice_group_registers : Register_group_register { + String group_id_str_; + Array voice_regs_l_; + + /* *************** */ + + NAME_MEMBERS(Voice_group_registers); + static bool static_acceptable_request_b(Request*); + virtual void terminate_register(Request_register*); + virtual void do_print() const; + virtual void add(Request_register*); + Voice_group_registers(String id); + virtual bool try_request(Request*); +}; +#endif // VOICEGROUPREGS_HH diff --git a/lily/include/voice-regs.hh b/lily/include/voice-regs.hh new file mode 100644 index 0000000000..82070a704e --- /dev/null +++ b/lily/include/voice-regs.hh @@ -0,0 +1,31 @@ +/* + voice-regs.hh -- declare Voice_registers + + source file of the LilyPond music typesetter + + (c) 1997 Han-Wen Nienhuys +*/ + + +#ifndef VOICEREGS_HH +#define VOICEREGS_HH + +#include "registergroup.hh" + +class Voice_registers : public Register_group_register { + + +public: + Voice *voice_l_; + /* *************** */ + + NAME_MEMBERS(Voice_registers); + virtual bool acceptable_request_b(Request*); + virtual void acknowledge_element(Staff_elem_info info); + virtual bool try_request(Request*); + Voice_registers(Voice*); + virtual void do_print() const; +}; + + +#endif // VOICEREGS_HH diff --git a/lily/include/voice.hh b/lily/include/voice.hh new file mode 100644 index 0000000000..06e6e1da27 --- /dev/null +++ b/lily/include/voice.hh @@ -0,0 +1,35 @@ +#ifndef VOICE_HH +#define VOICE_HH + +#include "proto.hh" +#include "plist.hh" +#include "moment.hh" + +/** class for horizontal stuff. + + Voice is a ordered row of Voice_elements. It is strictly + horizontal: you cannot have two rhythmic elements running parallel + in a Voice. For proper processing, each Voice should have + Group_change_req as a first element. + + */ + +struct Voice { + IPointerList elts; + Moment start; + + /* *************** */ + Voice(); + Voice(Voice const&); + + Moment when(const Voice_element*)const; + Moment last() const; + + void add(Voice_element*); + bool find_plet_start_bo(char c, Moment& moment_r); + void print() const; + void set_default_group(String id); + void set_plet_backwards(Moment& now_moment_r, Moment until_moment, int num_i, int den_i); +}; + +#endif diff --git a/lily/include/walk-regs.hh b/lily/include/walk-regs.hh new file mode 100644 index 0000000000..643ce57605 --- /dev/null +++ b/lily/include/walk-regs.hh @@ -0,0 +1,50 @@ +/* + walkregs.hh -- declare Walker_registers + + source file of the LilyPond music typesetter + + (c) 1997 Han-Wen Nienhuys +*/ + + +#ifndef WALKREGS_HH +#define WALKREGS_HH + + +#include "registergroup.hh" + +/** + Top level registers: the interface to Complex_walker. + + [sigh. Sometimes I wish C++ could do better late binding.] + */ +struct Walker_registers : Register_group_register { + Array prebreak_item_p_arr_; + Array nobreak_item_p_arr_; + Array postbreak_item_p_arr_; + Array announce_info_arr_; + Array group_l_arr_; + Complex_walker * walk_l_; + + /* *************** */ + void change_group(Group_change_req * greq_l, + Voice_registers *voice_regs_l, + Voice_group_registers * old_group); + Voice_group_registers * get_group(String id); + void typeset_musical_item(Staff_elem * elem_p); + Walker_registers(Complex_walker*); + void do_announces(); + void terminate_register(Request_register * reg); + virtual bool try_request(Request * r); + virtual Staff_info get_staff_info(); + + virtual void announce_element(Staff_elem_info); + virtual void acknowledge_element(Staff_elem_info); + virtual void typeset_breakable_item(Item * pre_p , Item * nobreak_p, Item * post_p); + virtual void typeset_element(Staff_elem*elem_p); + virtual void pre_move_processing(); + virtual void post_move_processing(); + virtual Paper_def * paper() const; +}; + +#endif // WALKREGS_HH diff --git a/lily/input-music.cc b/lily/input-music.cc new file mode 100644 index 0000000000..f1047e8bf9 --- /dev/null +++ b/lily/input-music.cc @@ -0,0 +1,252 @@ +#include "debug.hh" +#include "input-music.hh" +#include "voice.hh" +#include "musicalrequest.hh" +#include "voice-element.hh" + +void +Input_music::check_plet(Voice_element* velt_l) +{ + for (iter_top(velt_l->reqs,i); i.ok(); i++) + if ( i->plet() ) { + Moment start_moment = 0; + if ( !find_plet_start_bo( i->plet()->type_c_, start_moment ) ) { + error( "begin of plet not found", i->defined_ch_c_l_ ); + break; + } + Moment moment = 0; + set_plet_backwards( moment, start_moment, i->plet()->dur_i_, i->plet()->type_i_ ); + i.del(); + break; + } +} + +void +Simple_music::add(Voice_element*v) +{ + voice_.add(v); +} + +Moment +Simple_music::length()const +{ + return voice_.last(); +} +void +Simple_music::translate_time(Moment t) +{ + voice_.start += t; +} + +Voice_list +Simple_music::convert()const +{ + Voice_list l; + l.bottom().add(new Voice(voice_)); + return l; +} + + +void +Simple_music::print() const +{ + mtor << "Simple_music {"; + voice_.print(); + mtor << "}\n"; +} +bool +Simple_music::find_plet_start_bo(char c, Moment& moment_r) +{ + return voice_.find_plet_start_bo(c, moment_r); +} +void +Simple_music::set_plet_backwards(Moment& now_moment_r, Moment until_moment, int num_i, int den_i) +{ + voice_.set_plet_backwards(now_moment_r, until_moment, num_i, den_i); +} + +/* *************** */ + +void +Complex_music::add(Input_music*v) +{ + elts.bottom().add(v); +} + +void +Complex_music::print() const +{ + for (iter_top(elts,i); i.ok(); i++) + i->print(); +} + +void +Complex_music::concatenate(Complex_music*h) +{ + for (iter_top(h->elts,i); i.ok(); i++) + add(i->clone()); +} + +Complex_music::Complex_music() +{ +} + +Complex_music::Complex_music(Complex_music const&s) +{ + for (iter_top(s.elts,i); i.ok(); i++) + add(i->clone()); +} +void +Complex_music::set_default_group(String g) +{ + for (iter_top(elts,i); i.ok(); i++) + i->set_default_group(g); +} +bool +Complex_music::find_plet_start_bo(char c, Moment& moment_r) +{ + for (iter_bot(elts,i); i.ok(); i--) { + if ( i->find_plet_start_bo(c, moment_r) ) + return true; + } + return false; +} +void +Complex_music::set_plet_backwards(Moment& now_moment_r, Moment until_moment, int num_i, int den_i) +{ + for (iter_bot(elts,i); i.ok(); i--) { + i->set_plet_backwards(now_moment_r, until_moment, num_i, den_i); + } +} +/* *************************************************************** */ + +void +Music_voice::print() const +{ + mtor << "Music_voice {"; + Complex_music::print(); + mtor << "}\n"; +} + +void +Music_voice::add_elt(Voice_element*v) +{ + PCursor c(elts.bottom()); + if (!c.ok() || !c->simple()) { + Simple_music*vs = new Simple_music; + + c.add(vs); + } + + c = elts.bottom(); + Simple_music *s = c->simple(); + s->add(v); + + check_plet(v); +} + +Moment +Music_voice::length()const +{ + Moment l = 0; + + for (iter_top(elts,i); i.ok(); i++) + l += i->length(); + return l; +} + + +Voice_list +Music_voice::convert()const +{ + Voice_list l; + Moment here = 0; + + for (iter_top(elts,i); i.ok(); i++) { + Moment len = i->length(); + Voice_list k(i->convert()); + k.translate_time(here); + l.concatenate(k); + here +=len; + } + return l; +} + +void +Music_voice::translate_time(Moment t) +{ + elts.bottom()->translate_time(t); +} + + + +/* *************** */ + +void +Music_general_chord::add_elt(Voice_element*v) +{ + Simple_music*vs = new Simple_music; + vs->add(v); + elts.bottom().add(vs); + + check_plet(v); +} + +void +Music_general_chord::print() const +{ + mtor << "Music_general_chord {"; + Complex_music::print(); + mtor << "}\n"; +} + +void +Music_general_chord::translate_time(Moment t) +{ + for (iter_top(elts,i); i.ok(); i++) + i->translate_time(t); +} + +Moment +Music_general_chord::length()const +{ + Moment l =0; + + for (iter_top(elts,i); i.ok(); i++) + l = l >? i->length(); + return l; +} + +Voice_list +Music_general_chord::convert()const +{ + Voice_list l; + for (iter_top(elts,i); i.ok(); i++) { + Voice_list k(i->convert()); + l.concatenate(k); + } + return l; +} + +/* *************** */ + +void +Multi_voice_chord::set_default_group(String g) +{ + int j=0; + for (iter_top(elts, i); i.ok(); i++) { + i->set_default_group(g + String(j)); + j++; + } +} + + +/* *************** */ + +void +Voice_list::translate_time(Moment x) +{ + for (iter_top(*this,i); i.ok(); i++) + i->start += x; +} + diff --git a/lily/input-score.cc b/lily/input-score.cc new file mode 100644 index 0000000000..f39d47a4b1 --- /dev/null +++ b/lily/input-score.cc @@ -0,0 +1,102 @@ +/* + input-score.cc -- implement Input_score + + source file of the LilyPond music typesetter + + (c) 1997 Han-Wen Nienhuys +*/ + +#include "debug.hh" +#include "input-score.hh" +#include "input-staff.hh" +#include "input-music.hh" +#include "score.hh" +#include "paper-def.hh" +#include "midi-def.hh" +#include "staff.hh" + + +void +Input_score::add(Input_staff*s) +{ + staffs_.bottom().add(s); +} + +void +Input_score::set(Paper_def*p) +{ + delete paper_p_; + paper_p_ = p; +} + +void +Input_score::set(Midi_def* midi_p) +{ + delete midi_p_; + midi_p_ = midi_p; +} + +Input_score::Input_score(Input_score const&s) +{ + paper_p_ = (s.paper_p_)? new Paper_def(*s.paper_p_) :0; + midi_p_ = (s.midi_p_)? new Midi_def(*s.midi_p_) : 0; + defined_ch_c_l_ = s.defined_ch_c_l_; + errorlevel_i_ = s.errorlevel_i_; + score_wide_music_p_ = (s.score_wide_music_p_) ? + s.score_wide_music_p_->clone():0; +} + +Score* +Input_score::parse() +{ + Score *s_p = new Score; + s_p->defined_ch_c_l_= defined_ch_c_l_; + s_p->errorlevel_i_ = errorlevel_i_; + if (midi_p_) + s_p->set(new Midi_def(*midi_p_)); + if (paper_p_) + s_p->set( new Paper_def(*paper_p_)); + + for (iter_top(staffs_,i); i.ok(); i++) { + Staff* staf_p=i->parse(s_p, score_wide_music_p_); + s_p->add(staf_p); + } + + return s_p; +} + +void +Input_score::set(Input_music *m_p) +{ + delete score_wide_music_p_; + score_wide_music_p_ =m_p; +} + + +Input_score::~Input_score() +{ + delete paper_p_; + delete score_wide_music_p_; + delete midi_p_; +} + +Input_score::Input_score() +{ + score_wide_music_p_ =0; + defined_ch_c_l_=0; + paper_p_= 0; + midi_p_ = 0; + errorlevel_i_ = 0; +} + +void +Input_score::print()const +{ +#ifndef NPRINT + mtor << "Input_score {\n"; + for (iter_top(staffs_,i); i.ok(); i++) { + i->print(); + } + mtor << "}\n"; +#endif +} diff --git a/lily/input-staff.cc b/lily/input-staff.cc new file mode 100644 index 0000000000..8305a094a9 --- /dev/null +++ b/lily/input-staff.cc @@ -0,0 +1,88 @@ +/* + input-staff.cc -- implement Input_staff + + source file of the LilyPond music typesetter + + (c) 1997 Han-Wen Nienhuys +*/ + +#include "debug.hh" +#include "score.hh" +#include "input-music.hh" +#include "input-staff.hh" +#include "staff.hh" +#include "complex-staff.hh" +#include "lyric-staff.hh" + +#include "lexer.hh" + + +Input_staff::Input_staff(String s) +{ + score_wide_music_p_ =0; + type= s; + defined_ch_c_l_ = 0; +} + +void +Input_staff::add(Input_music*m) +{ + music_.bottom().add(m); +} + +Staff* +Input_staff::parse(Score*score_l, Input_music *default_score_wide) +{ + Staff *p=0; + if (type == "melodic") + p = new Complex_staff; + else if (type == "lyric") + p = new Lyric_staff; + else { + error( "Unknown staff-type `" + type +"\'", defined_ch_c_l_ ); + exit( 1 ); + } + + p->score_l_ = score_l; + + for (iter_top(music_,i); i.ok(); i++) { + Voice_list vl = i->convert(); + p->add(vl); + } + Voice_list vl = (score_wide_music_p_) ? score_wide_music_p_->convert() + : default_score_wide->convert(); + p->add(vl); + return p; +} + +Input_staff::Input_staff(Input_staff const&s) +{ + for (iter_top(s.music_,i); i.ok(); i++) + add(i->clone()); + defined_ch_c_l_ = s.defined_ch_c_l_; + type = s.type; + score_wide_music_p_ = (s.score_wide_music_p_) ? + s.score_wide_music_p_->clone() : 0; +} + +void +Input_staff::print() const +{ +#ifndef NPRINT + mtor << "Input_staff {\n"; + for (iter_top(music_,i); i.ok(); i++) + i->print(); + mtor << "}\n"; +#endif +} +void +Input_staff::set_score_wide(Input_music *m_p) +{ + delete score_wide_music_p_; + score_wide_music_p_ = m_p; +} + +Input_staff::~Input_staff() +{ + delete score_wide_music_p_; +} diff --git a/lily/item.cc b/lily/item.cc new file mode 100644 index 0000000000..e653c46ac6 --- /dev/null +++ b/lily/item.cc @@ -0,0 +1,18 @@ +#include "debug.hh" +#include "item.hh" + + + +Item::Item() +{ + pcol_l_ = 0; +} + +void +Item::do_print() const +{ +#ifndef NPRINT + mtor << "(unknown)"; +#endif +} + diff --git a/lily/key-item.cc b/lily/key-item.cc new file mode 100644 index 0000000000..963b1bc578 --- /dev/null +++ b/lily/key-item.cc @@ -0,0 +1,70 @@ +#include "key-item.hh" +#include "key.hh" +#include "debug.hh" +#include "molecule.hh" +#include "paper-def.hh" +#include "lookup.hh" +//#include "clef-reg.hh" +#include "key-reg.hh" + +const int FLAT_TOP_PITCH=2; /* fes,ges,as and bes typeset in lower octave */ +const int SHARP_TOP_PITCH=4; /* ais and bis typeset in lower octave */ + + + +Key_item::Key_item(int c) +{ + set_c_position(c); +} + +void +Key_item::read(const Key_register& key_reg_r) +{ + const Array &idx_arr =key_reg_r.accidental_idx_arr_; + for (int i = 0 ; i< idx_arr.size(); i++) { + int note = idx_arr[i]; + int acc = key_reg_r.key_.acc(note); + + add(note, acc); + } +} + +void +Key_item::set_c_position(int c0) +{ + int octaves =(abs(c0) / 7) +1 ; + c_position=(c0 + 7*octaves)%7; +} + + +void +Key_item::add(int p, int a) +{ + if ((a<0 && p>FLAT_TOP_PITCH) || + (a>0 && p>SHARP_TOP_PITCH)) { + p -= 7; /* Typeset below c_position */ + } + pitch.push(p); + acc.push(a); +} + + +Molecule* +Key_item::brew_molecule_p()const +{ + Molecule*output = new Molecule; + Real inter = paper()->internote(); + + for (int i =0; i < pitch.size(); i++) { + Symbol s= paper()->lookup_p_->accidental(acc[i]); + Atom a(s); + a.translate(Offset(0,(c_position + pitch[i]) * inter)); + Molecule m(a); + output->add_right(m); + } + Molecule m(paper()->lookup_p_->fill(Box( + Interval(0, paper()->note_width()), + Interval(0,0)))); + output->add_right(m); + return output; +} diff --git a/lily/key-reg.cc b/lily/key-reg.cc new file mode 100644 index 0000000000..84b0e268c6 --- /dev/null +++ b/lily/key-reg.cc @@ -0,0 +1,99 @@ +/* + key-reg.cc -- implement Key_register + + source file of the LilyPond music typesetter + + (c) 1997 Han-Wen Nienhuys + + todo: key undo + + */ +#include "time-description.hh" +#include "key-reg.hh" +#include "key-item.hh" +#include "commandrequest.hh" +#include "staff-column.hh" +#include "local-key-reg.hh" +#include "musicalrequest.hh" + +Key_register::Key_register() +{ + post_move_processing(); +} + +bool +Key_register::try_request(Request * req_l) +{ + Command_req* creq_l= req_l->command(); + if (!creq_l|| !creq_l->keychange()) + return false; + + assert(!keyreq_l_); // todo + keyreq_l_ = creq_l->keychange(); + read_req(keyreq_l_); + return true; +} + +void +Key_register::acknowledge_element(Staff_elem_info info) +{ + Command_req * r_l = info.req_l_->command() ; + if (r_l && r_l->clefchange() && !kit_p_) { + int c0_i= *get_staff_info().c0_position_i_; + kit_p_ = new Key_item(c0_i); + kit_p_->read(*this); + announce_element(Staff_elem_info(kit_p_, keyreq_l_)); + } +} + +void +Key_register::process_requests() +{ + const Time_description *time_l = get_staff_info().time_c_l_; + + if (!keyreq_l_ && + (!time_l->whole_in_measure_|| !time_l->when_)) { + default_key_b_ = true; + } + + if ( default_key_b_ || keyreq_l_) { + int c0_i= *get_staff_info().c0_position_i_; + kit_p_ = new Key_item(c0_i); + kit_p_->read(*this); + announce_element(Staff_elem_info(kit_p_, keyreq_l_)); + } +} + +void +Key_register::pre_move_processing() +{ + if (kit_p_) { + if (default_key_b_) + typeset_breakable_item(0,0,kit_p_); + else + typeset_breakable_item( + new Key_item(*kit_p_), kit_p_, new Key_item(*kit_p_)); + kit_p_ = 0; + } +} + + + +void +Key_register::read_req(Key_change_req * r) +{ + accidental_idx_arr_.set_size(0); + for (int i = 0; i < r->melodic_p_arr_.size(); i ++) { + int n_i=r->melodic_p_arr_[i]->notename_i_; + key_.set(n_i, r->melodic_p_arr_[i]->accidental_i_); + accidental_idx_arr_.push(n_i); + } +} + +void +Key_register::post_move_processing() +{ + keyreq_l_ = 0; + default_key_b_ = false; + kit_p_ = 0; +} diff --git a/lily/key.cc b/lily/key.cc new file mode 100644 index 0000000000..7e23464ccf --- /dev/null +++ b/lily/key.cc @@ -0,0 +1,38 @@ +#include "key.hh" + +const int OCTAVES=14; // ugh.. +const int ZEROOCTAVE=7; + +Key::Key() +{ + accidental_i_arr_.set_size(7); + for (int i= 0; i < 7 ; i++) + accidental_i_arr_[i] = 0; +} + +Local_key::Local_key() +{ + octaves.set_size(OCTAVES); +} + +Key& +Local_key::oct(int i) +{ + return octaves[i+ZEROOCTAVE]; +} + +void +Key::set(int i, int a) +{ + assert(a > -3 && a < 3); + accidental_i_arr_[i]=a; +} + + +void +Local_key::reset(Key k) +{ + for (int i= 0; i < OCTAVES ; i++) + octaves[i] = k; +} + diff --git a/lily/keyword.cc b/lily/keyword.cc new file mode 100644 index 0000000000..14903cfb61 --- /dev/null +++ b/lily/keyword.cc @@ -0,0 +1,79 @@ +/* + keyword.cc -- keywords and identifiers + */ + +#include + +#include "glob.hh" +#include "lexer.hh" +//#include "mudobs.hh" +//#include "gram.hh" + +/* for the keyword table */ +struct Keyword_ent +{ + const char *name; + int tokcode; +}; + +struct Keyword_table +{ + Keyword_ent *table; + int maxkey; + Keyword_table(Keyword_ent *); + int lookup(const char *s) const; +}; + + +/* for qsort */ +int + tabcmp(const void * p1, const void * p2) +{ + return strcmp(((const Keyword_ent *) p1)->name, + ((const Keyword_ent *) p2)->name); +} + +Keyword_table::Keyword_table(Keyword_ent *tab) +{ + table = tab; + + /* count keywords */ + for (maxkey = 0; table[maxkey].name; maxkey++); + + /* sort them */ + qsort(table, maxkey, sizeof(Keyword_ent), tabcmp); +} + +/* + lookup with binsearch, return tokencode. +*/ +int +Keyword_table::lookup(const char *s)const +{ + int lo, + hi, + cmp, + result; + lo = 0; + hi = maxkey; + + /* binary search */ + do + { + cmp = (lo + hi) / 2; + + result = strcmp(s, table[cmp].name); + + if (result < 0) + hi = cmp; + else + lo = cmp; + } + while (hi - lo > 1); + if (!strcmp(s, table[lo].name)) + { + return table[lo].tokcode; + } else + return -1; /* not found */ +} + diff --git a/lily/leastsquares.cc b/lily/leastsquares.cc new file mode 100644 index 0000000000..cf9ec478e4 --- /dev/null +++ b/lily/leastsquares.cc @@ -0,0 +1,35 @@ +#include "leastsquares.hh" +void +Least_squares::OK() const +{ + assert( input.size() > 1 ); + Real dx = 0.0; + for (int i=1; i < input.size(); i++) + dx += abs (input[i-1].x - input[i].x); + + assert(dx); +} +void +Least_squares::minimise(Real &coef, Real &offset) +{ + OK(); + Real sx = 0.0; + Real sy = 0.0; + Real sqx =0.0; + Real sxy = 0.0; + + for (int i=0; i < input.size();i++) { + Real x=input[i].x; + Real y = input[i].y; + sx += x; + sy += y; + sqx += sqr(x); + sxy += x*y; + } + int N = input.size(); + + + coef = (N * sxy - sx*sy )/(N*sqx - sqr(sx)); + offset = (sy - coef * sx)/N; + +} diff --git a/lily/lexer.l b/lily/lexer.l new file mode 100644 index 0000000000..6f5945a605 --- /dev/null +++ b/lily/lexer.l @@ -0,0 +1,281 @@ +%{ // -*-Fundamental-*- + +#include + +#include "string.hh" +#include "string-convert.hh" +#include "notename.hh" +#include "lexer.hh" +#include "varray.hh" +#include "parser.hh" +#include "debug.hh" +#include "input-score.hh" +#include "parseconstruct.hh" +#include "main.hh" + +%} + +%option c++ +%option noyywrap +%option nodefault +%option yylineno +%option debug +%option yyclass="My_flex_lexer" +%option stack + +%x notes +%x incl +%x quote +%x lyrics + + + +A [a-zA-Z] +AA {A}|_ +N [0-9] +AN {AA}|{N} +PUNCT [?!,.:;] +ACCENT [\\'"^] +NATIONAL [\241-\377] +TEX {AA}|-|{PUNCT}|{ACCENT}|{NATIONAL} + +WORD {A}{AN}* +ALPHAWORD {A}+ +INT -?{N}+ +REAL {INT}?(\.{N}*)? + +OPTSIGN !? +PITCHMOD ['`]*{OPTSIGN} +RESTNAME r|s|p +NOTECOMMAND \\{WORD} +NOTENAME [a-z]+ +UNOTENAME [A-Z][a-z]* +DOTS \.+ +LYRICS {TEX}+ +COMMENT [%#].*\n + +%% + +\$ { + yy_push_state(notes); +} + +\@ { + yy_push_state(lyrics); +} + +{RESTNAME} { + const char *s = YYText(); + yylval.string = new String (s); + mtor << "rest:"<< yylval.string; + return RESTNAME; +} +{UNOTENAME} { + int *p=yylval.ii; + return ret_notename(p, YYText(), -1); +} + +{NOTENAME} { + int *p=yylval.ii; + return ret_notename(p, YYText(), 0); +} + +{NOTECOMMAND} { + String c = YYText() +1; + mtor << "\\word: " << YYText()+1<{PITCHMOD} { + const char *s = YYText(); + mtor << "pitchmod:"<< YYText()<{DOTS} { + yylval.i = strlen(YYText()); + return DOTS; +} +{INT} { + yylval.i = String_convert::dec2_i( String( YYText() ) ); + return INT; +} +{COMMENT} { +} +[ \t\n]+ { + +} +\$ { + yy_pop_state(); +} +\"[^"]*\" { + String s (YYText()+1); + s = s.left_str(s.length_i()-1); + yylval.string = new String(s); + return STRING; +} +. { + return yylval.c = YYText()[0]; +} + +\" { + yy_push_state(quote); +} +[^"]* { + yylval.string = new String (YYText()); +} +\" { + mtor << "quoted string\n"; + yy_pop_state(); + return STRING; +} + +{DOTS} { + yylval.i = strlen(YYText()); + return DOTS; +} +{INT} { + yylval.i = String_convert::dec2_i( String( YYText() ) ); + return INT; +} +{NOTECOMMAND} { + String c = YYText() +1; + mtor << "\\word: " << YYText()+1<\"[^"]*\" { + String s (YYText()+1); + s = s.left_str(s.length_i()-1); + yylval.string = new String(s); + return STRING; +} +{LYRICS} { + String s (YYText()); + int i = 0; + while ((i=s.index_i("_")) != -1) // change word binding "_" to " " + *(s.ch_l() + i) = ' '; + if ((i=s.index_i("\\,")) != -1) // change "\," to TeX's "\c " + { + *(s.ch_l() + i + 1) = 'c'; + s = s.left_str(i+2) + " " + s.right_str(s.length_i()-i-2); + } + yylval.string = new String(s); + return STRING; +} +\| { + return YYText()[0]; +} +{COMMENT} { + +} +[{}] { + return YYText()[0]; +} +[()\[\]|/.^>_-] { + return yylval.c = YYText()[0]; +} +[ \t\n]+ { +} +@ { + yy_pop_state(); +} + +<> { + mtor << "<>"; + + if (! close_input()) + yyterminate(); // can't move this, since it actually rets a YY_NULL +} + + +include { + yy_push_state(incl); +} +[ \t]* { /* eat the whitespace */ } +\"[^"]*\"+ { /* got the include file name */ + String s (YYText()+1); + s = s.left_str(s.length_i()-1); + defined_ch_c_l = here_ch_c_l() - String( YYText() ).length_i() - 1; + new_input(s); + yy_pop_state(); +} + + +{WORD} { + mtor << "word: " << YYText()< +*/ + +#include +#include +#include "proto.hh" +#include "plist.hh" +#include "lexer.hh" +#include "debug.hh" +#include "main.hh" +#include "source-file.hh" +#include "source.hh" + +My_flex_lexer *lexer=0; + +int +yylex() { + return lexer->yylex(); +} + +bool +busy_parsing() +{ + return lexer; +} diff --git a/lily/linespace.cc b/lily/linespace.cc new file mode 100644 index 0000000000..a7bfa1df9b --- /dev/null +++ b/lily/linespace.cc @@ -0,0 +1,288 @@ +#include +#include "linespace.hh" +#include "pcol.hh" +#include "debug.hh" +#include "qlp.hh" +#include "unionfind.hh" +#include "idealspacing.hh" + +const Real COLFUDGE=1e-3; + + +bool +Spacing_problem::contains(const PCol *w) +{ + for (int i=0; i< cols.size(); i++) + if (cols[i].pcol_ == w) + return true; + return false; +} + +int +Spacing_problem::col_id(const PCol *w)const +{ + for (int i=0; i< cols.size(); i++) + if (cols[i].pcol_ == w) + return i; + assert(false); + return -1; +} + +void +Spacing_problem::OK() const +{ +#ifndef NDEBUG + Union_find connected(cols.size()); + Array fixed; + for (int i=0; i < ideals.size(); i++) { + assert(ideals[i]->hooke > 0); + int l = col_id(ideals[i]->left); + int r = col_id(ideals[i]->right); + connected.connect(l,r); + } + for (int i = 0; i < cols.size(); i++) + if (cols[i].fixed()) + fixed.push(i); + for (int i = 0; i < cols.size(); i++) { + bool c=false; + for (int j =0; j COLFUDGE) + return false; + + if (!i) + continue; + + Real mindist=cols[i-1].minright() + +cols[i].minleft(); + + // ugh... compares + Real dif =v(i) - v(i-1)- mindist; + bool b = (dif > - COLFUDGE); + + + if (!b) + return false; + + } + return true; +} + +bool +Spacing_problem::check_feasible() const +{ + Vector sol(try_initial_solution()); + return check_constraints(sol); +} + +// generate a solution which obeys the min distances and fixed positions +Vector +Spacing_problem::try_initial_solution() const +{ + int dim=cols.size(); + Vector initsol(dim); + for (int i=0; i < dim; i++) { + if (cols[i].fixed()) { + initsol(i)=cols[i].fixed_position(); + } else { + Real mindist=cols[i-1].minright() + +cols[i].minleft(); + assert(mindist >= 0.0); + initsol(i)=initsol(i-1)+mindist; + + //nog niet + //if (i>0) + // assert(initsol(i) > initsol(i-1)); + } + } + + return initsol; +} +Vector +Spacing_problem::find_initial_solution() const +{ + Vector v(try_initial_solution()); + assert(check_constraints(v)); + return v; +} + +// generate the matrices +void +Spacing_problem::make_matrices(Matrix &quad, Vector &lin, Real &c) const +{ + quad.fill(0); + lin.fill(0); + c = 0; + for (int j=0; j < ideals.size(); j++){ + Idealspacing const*i=ideals[j]; + int l = col_id(i->left); + int r = col_id(i->right); + + quad(r,r) += i->hooke; + quad(r,l) -= i->hooke; + quad(l,r) -= i->hooke; + quad(l,l) += i->hooke; + + lin(r) -= i->space*i->hooke; + lin(l) += i->space*i->hooke; + + c += sqr(i->space); + } +} + +// put the constraints into the LP problem +void +Spacing_problem::make_constraints(Mixed_qp& lp) const +{ + int dim=cols.size(); + for (int j=0; j < dim; j++) { + Colinfo *c=&(cols[j]); + if (c->fixed()) { + lp.add_fixed_var(j,c->fixed_position()); + } + if (j > 0){ + Vector c1(dim); + + c1(j)=1.0 ; + c1(j-1)=-1.0 ; + lp.add_inequality_cons(c1, cols[j-1].minright() + + cols[j].minleft()); + } + } +} + +Array +Spacing_problem::solve() const +{ + print(); + OK(); + assert(check_feasible()); + + /* optimalisatiefunctie */ + Mixed_qp lp(cols.size()); + make_matrices(lp.quad,lp.lin, lp.const_term); + make_constraints(lp); + Vector start=find_initial_solution(); + Vector sol(lp.solve(start)); + if (!check_constraints(sol)) { + WARN << "solution doesn't satisfy constraints.\n" ; + } + + + Array posns(sol); + posns.push(lp.eval(sol)); + return posns; +} + +/* + add one column to the problem. +*/ +void +Spacing_problem::add_column(const PCol *col, bool fixed, Real fixpos) +{ + Colinfo c(col,(fixed)? &fixpos : 0); + cols.push(c); +} + +void +Spacing_problem::add_ideal(const Idealspacing *i) +{ + const PCol *l =i->left; + const PCol *r= i->right; + + if (!contains(l) || !contains(r)) { + return; + } + ideals.push(i); +} + +void +Spacing_problem::print_ideal(const Idealspacing*id)const +{ +#ifndef NPRINT + int l = col_id(id->left); + int r = col_id(id->right); + + mtor << "between " << l <<","<print(); +#endif +} + +void +Spacing_problem::print() const +{ +#ifndef NPRINT + for (int i=0; i < cols.size(); i++) { + mtor << "col " << i<<' '; + cols[i].print(); + } + for (int i=0; i < ideals.size(); i++) { + print_ideal(ideals[i]); + } +#endif + +} + +/* **************** */ + +void +Colinfo::print() const +{ +#ifndef NPRINT + mtor << "column { "; + if (fixed()) + mtor << "fixed at " << fixed_position()<<", "; + assert(pcol_); + mtor << "[" << minleft() << ", " << minright() << "]"; + mtor <<"}\n"; +#endif +} + +Colinfo::Colinfo(Colinfo const&c) +{ + fixpos = (c.fixpos)?new Real(*c.fixpos):0; + pcol_ = c.pcol_; + width = c.width; +} + +Colinfo::Colinfo(const PCol*col_p, const Real*fixed_r_p ) +{ + fixpos = (fixed_r_p)? new Real(*fixed_r_p) : 0; + pcol_ = col_p; + width = pcol_->width(); +} + +Colinfo::~Colinfo() +{ + delete fixpos; +} + +Colinfo::Colinfo() +{ + pcol_=0; + fixpos = 0; +} +void +Colinfo::operator=(Colinfo const&c ) +{ + delete fixpos; + fixpos = (c.fixpos)?new Real(*c.fixpos):0; + pcol_ = c.pcol_; + width = c.width; +} diff --git a/lily/local-key-item.cc b/lily/local-key-item.cc new file mode 100644 index 0000000000..425982120c --- /dev/null +++ b/lily/local-key-item.cc @@ -0,0 +1,93 @@ +#include "local-key-item.hh" +#include "molecule.hh" +#include "scalar.hh" +#include "lookup.hh" +#include "paper-def.hh" +#include "musicalrequest.hh" +#include "notehead.hh" +#include "misc.hh" + + + +Local_key_item::Local_key_item(int i) +{ + c0_position = i; +} + +void +Local_key_item::add(Item*head_l) +{ + support_items_.push(head_l); + add_dependency(head_l); +} + +void +Local_key_item::add(Melodic_req*m_l) +{ + add(m_l->octave_i_, m_l->notename_i_, m_l->accidental_i_); +} +void +Local_key_item::add (int o, int p , int a) +{ + Local_acc l; + l.octave = o; + l.name = p; + l.acc = a; + accs.push(l); +} + +void +Local_key_item::do_pre_processing() +{ + accs.sort(Local_acc::compare); +} + +Molecule* +Local_key_item::brew_molecule_p()const +{ + Molecule* output = new Molecule; + Molecule*octmol = 0; + int lastoct = -100; + for (int i = 0; i < accs.size(); i++) { + // do one octave + if (accs[i].octave != lastoct) { + if (octmol){ + Real dy =lastoct*7*paper()->internote(); + octmol->translate(Offset(0, dy)); + output->add(*octmol); + delete octmol; + } + octmol= new Molecule; + } + lastoct = accs[i].octave; + Symbol s =paper()->lookup_p_->accidental(accs[i].acc); + Atom a(s); + Real dy = (accs[i].name + c0_position) * paper()->internote(); + a.translate(Offset(0,dy)); + + octmol->add_right(a); + } + + if (octmol){ + Real dy =lastoct*7*paper()->internote(); + octmol->translate(Offset(0, dy)); + output->add(*octmol); + delete octmol; + } + + Interval head_width=itemlist_width(support_items_); + output->translate(Offset(-output->extent().x.right + head_width.left ,0)); + + return output; +} + +int +Local_acc::compare(Local_acc&a, Local_acc&b) +{ + if (a.octave - b.octave) + return a.octave - b.octave; + if (a.name - b.name) + return a.name - b.name; + + assert(false); +}; diff --git a/lily/local-key-reg.cc b/lily/local-key-reg.cc new file mode 100644 index 0000000000..f13ec98b9f --- /dev/null +++ b/lily/local-key-reg.cc @@ -0,0 +1,69 @@ +/* + local-key-reg.cc -- implement Local_key_register + + (c) 1997 Han-Wen Nienhuys +*/ + +#include "musicalrequest.hh" +#include "commandrequest.hh" +#include "local-key-reg.hh" +#include "local-key-item.hh" +#include "complex-walker.hh" +#include "key-reg.hh" +#include "debug.hh" +#include "key-item.hh" + +Local_key_register::Local_key_register() +{ + key_item_p_ = 0; + key_c_l_ = 0; +} + +void +Local_key_register::pre_move_processing() +{ + if (key_item_p_) { + typeset_element(key_item_p_); + key_item_p_ = 0; + } +} +void +Local_key_register::acknowledge_element(Staff_elem_info info) +{ + if (info.req_l_->melodic()) { + Melodic_req * melodic_l_ = info.req_l_->melodic(); + + if( melodic_l_->forceacc_b_ || + local_key_.oct(melodic_l_->octave_i_).acc(melodic_l_->notename_i_) + != melodic_l_->accidental_i_) { + Item * support_l_ = info.elem_p_->item(); + + + if (!key_item_p_) { + key_item_p_ = new Local_key_item(*get_staff_info().c0_position_i_); + } + + key_item_p_->add(melodic_l_); + key_item_p_->add(support_l_); + local_key_.oct(melodic_l_->octave_i_) + .set(melodic_l_->notename_i_, melodic_l_->accidental_i_); + } + } else if (info.elem_p_->name()==Key_item::static_name()) { + Key_register * key_reg_l = + (Key_register*)info.origin_reg_l_arr_[0]; + key_c_l_ = &key_reg_l->key_; + local_key_.reset(*key_c_l_); + } +} + +void +Local_key_register::process_requests() +{ + const Time_description * time_c_l_ = get_staff_info().time_c_l_; + if (! time_c_l_->whole_in_measure_){ + if (key_c_l_) + local_key_.reset(*key_c_l_); + else if( time_c_l_->when_ >Moment(0)) + warning ("Help me! can't figure current key", 0); + } +} diff --git a/lily/lookup.cc b/lily/lookup.cc new file mode 100644 index 0000000000..ffd668e75d --- /dev/null +++ b/lily/lookup.cc @@ -0,0 +1,222 @@ +/* + lookup.cc -- implement simple Lookup methods. + + source file of the LilyPond music typesetter + + (c) 1997 Han-Wen Nienhuys +*/ + +#include "lookup.hh" +#include "debug.hh" +#include "symtable.hh" +#include "dimen.hh" +#include "tex.hh" +#include "scalar.hh" + +Lookup::Lookup() +{ + texsetting = "\\unknowntexsetting"; + symtables_ = new Symtables; +} + +Lookup::Lookup(Lookup const &s) +{ + texsetting = s.texsetting; + symtables_ = new Symtables(*s.symtables_); +} +Lookup::~Lookup() +{ + delete symtables_; +} + +void +Lookup::add(String s, Symtable*p) +{ + symtables_->add(s, p); +} + +void +Lookup::print()const +{ + mtor << "Lookup: " << texsetting << " {\n"; + symtables_->print(); + mtor << "}\n"; +} + +Symbol +Lookup::text(String style, String text, int dir) +{ + Array a; + + a.push(text); + Symbol tsym = (*symtables_)("style")->lookup(style); + a[0] = substitute_args(tsym.tex,a); + + Symbol s = (*symtables_)("align")->lookup(dir); + s.tex = substitute_args(s.tex,a); + s.dim.y = tsym.dim.y; + return s; +} + + +Real +Lookup::internote() +{ + return ball(4).dim.y.length()/2; +} + +Symbol +Lookup::ball(int j) +{ + if (j > 4) + j = 4; + + Symtable * st = (*symtables_)("balls"); + return st->lookup(String(j)); +} + +Symbol +Lookup::rest(int j) +{ + return (*symtables_)("rests")->lookup(String(j)); +} + +Symbol +Lookup::fill(Box b) +{ + Symbol s( (*symtables_)("param")->lookup("fill")); + s.dim = b; + return s; +} + +Symbol +Lookup::accidental(int j) +{ + return (*symtables_)("accidentals")->lookup(String(j)); +} + + +Symbol +Lookup::bar(String s) +{ + return (*symtables_)("bars")->lookup(s); +} + +Symbol +Lookup::script(String s) +{ + return (*symtables_)("scripts")->lookup(s); +} + +Symbol +Lookup::clef(String s) +{ + return (*symtables_)("clefs")->lookup(s); +} + +Symbol +Lookup::dots(int j) +{ + if (j>3) + error("max 3 dots"); // todo + return (*symtables_)("dots")->lookup(j); +} + +Symbol +Lookup::flag(int j) +{ + return (*symtables_)("flags")->lookup(j); +} + +Symbol +Lookup::streepjes(int i) +{ + assert(i); + + int arg; + String idx; + + if (i < 0) { + idx = "botlines"; + arg = -i; + } else { + arg = i; + idx = "toplines"; + } + Symbol ret = (*symtables_)("streepjes")->lookup(idx); + + Array a; + a.push(arg); + ret.tex = substitute_args(ret.tex, a); + + return ret; +} + +Symbol +Lookup::hairpin(Real &wid, bool decresc) +{ + int idx = int(rint(wid / 6 PT)); + if(!idx) idx ++; + wid = idx*6 PT; + String idxstr = (decresc)? "decrescendosym" : "crescendosym"; + Symbol ret=(*symtables_)("param")->lookup(idxstr); + + Array a; + a.push(idx); + ret.tex = substitute_args(ret.tex, a); + ret.dim.x = Interval(0,wid); + return ret; +} + +Symbol +Lookup::linestaff(int lines, Real wid) +{ + Symbol s; + s.dim.x = Interval(0,wid); + Real dy = (lines >0) ? (lines-1)*internote()*2 : 0; + s.dim.y = Interval(0,dy); + + Array a; + a.push(lines); + a.push(print_dimen(wid)); + + s.tex = (*symtables_)("param")->lookup("linestaf").tex; + s.tex = substitute_args(s.tex, a); + + return s; +} + + +Symbol +Lookup::meter(Array a) +{ + Symbol s; + s.dim.x = Interval( 0 PT, 10 PT); + s.dim.y = Interval(0, 20 PT); // todo + String src = (*symtables_)("param")->lookup("meter").tex; + s.tex = substitute_args(src,a); + return s; +} + + +Symbol +Lookup::stem(Real y1,Real y2) +{ + if (y1 > y2) { + Real t = y1; + y1 = y2; + y2 = t; + } + Symbol s; + + s.dim.x = Interval(0,0); + s.dim.y = Interval(y1,y2); + + Array a; + a.push(print_dimen(y1)); + a.push(print_dimen(y2)); + + String src = (*symtables_)("param")->lookup("stem").tex; + s.tex = substitute_args(src,a); + return s; +} diff --git a/lily/lyric-item.cc b/lily/lyric-item.cc new file mode 100644 index 0000000000..c0adac7b63 --- /dev/null +++ b/lily/lyric-item.cc @@ -0,0 +1,27 @@ +#include "musicalrequest.hh" +#include "paper-def.hh" +#include "lyric-item.hh" +#include "stem.hh" +#include "molecule.hh" +#include "lookup.hh" +#include "text-def.hh" +#include "source-file.hh" +#include "source.hh" +#include "debug.hh" +#include "main.hh" + +Lyric_item::Lyric_item(Lyric_req* lreq_l, int voice_count_i) + : Text_item(lreq_l,0) +{ + pos_i_ = -voice_count_i * 4 ; // 4 fontsize dependant. TODO + dir_i_ = -1; +} + +void +Lyric_item::do_pre_processing() +{ + + // test context-error + if ( tdef_l_->text_str_.index_i( "Gates" ) >=0)// :-) + warning( "foul word", tdef_l_->defined_ch_c_l_ ); +} diff --git a/lily/lyric-staff.cc b/lily/lyric-staff.cc new file mode 100644 index 0000000000..8414f4ecaf --- /dev/null +++ b/lily/lyric-staff.cc @@ -0,0 +1,22 @@ +#include "musicalrequest.hh" +#include "voice.hh" +#include "staff-walker.hh" +#include "debug.hh" +#include "staff.hh" +#include "lyric-staff.hh" +#include "lyric-walker.hh" +#include "pscore.hh" + +void +Lyric_staff::set_output(PScore*pscore_l) +{ + pstaff_l_ = new PStaff(pscore_l); + pscore_l_ = pscore_l; + pscore_l_->add(pstaff_l_); +} + +Staff_walker* +Lyric_staff::get_walker_p() +{ + return new Lyric_walker(this); +} diff --git a/lily/main.cc b/lily/main.cc new file mode 100644 index 0000000000..1073f940bf --- /dev/null +++ b/lily/main.cc @@ -0,0 +1,168 @@ +#include +#include +#include "proto.hh" +#include "plist.hh" +#include "lgetopt.hh" +#include "misc.hh" +#include "string.hh" +#include "main.hh" +#include "path.hh" +#include "config.hh" +#include "source-file.hh" +#include "source.hh" + +Source source; +Source* source_l_g = &source; +String infile_str_g; +bool only_midi = false; +extern void parse_file(String,String); + + +void +destill_inname( String &name_str_r); +Long_option_init theopts[] = { + 1, "output", 'o', + 0, "warranty", 'w', + 0, "help", 'h', + 0, "debug", 'd', + 1, "init", 'i', + 1, "include", 'I', + 0, "midi", 'M', + 0,0,0 +}; + +void +help() +{ + cout << + "--help, -h This help\n" + "--warranty, -w show warranty & copyright\n" + "--output, -o set default output\n" + "--debug, -d enable debug output\n" + "--init, -i set init file\n" + "--include, -I add to file search path.\n" + "--midi, -M midi output only\n" + ; + +} + +void +notice() +{ + cout << + "\n" + "LilyPond, a music typesetter.\n" + "Copyright (C) 1996,97 by\n" + " Han-Wen Nienhuys \n" + "Contributors\n" + " Jan Nieuwenhuizen \n" + " Mats Bengtsson \n" + "\n" + " This program is free software; you can redistribute it and/or\n" + "modify it under the terms of the GNU General Public License version 2\n" + "as published by the Free Software Foundation.\n" + "\n" + " This program is distributed in the hope that it will be useful,\n" + "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" + "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n" + "General Public License for more details.\n" + "\n" + " You should have received a copy (refer to the file COPYING) of the\n" + "GNU General Public License along with this program; if not, write to\n" + "the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,\n" + "USA.\n"; +} + +static File_path * path =0; +struct Main_init { + Main_init() { + path = new File_path(LIBDIR); + path->push(String(LIBDIR)+"init/"); + debug_init(); + } + ~Main_init() { + delete path; + } +} main_init; + +int +main (int argc, char **argv) +{ + Getopt_long oparser(argc, argv,theopts); + cout << get_version(); + String init_str("symbol.ini"); + + while (Long_option_init * opt = oparser()) { + switch ( opt->shortname){ + case 'o': + set_default_output(oparser.optarg); + break; + case 'w': + notice(); + exit(0); + break; + case 'I': + path->push(oparser.optarg); + break; + case 'i': + init_str = oparser.optarg; + break; + case 'h': + help(); + exit(0); + break; + case 'd': + set_debug(true); + break; + case 'M': + only_midi = true; + break; + default: + assert(false); + break; + } + } + + int p=0; + char *arg ; + while ( (arg= oparser.get_next_arg()) ) { + String f(arg); + destill_inname(f); + infile_str_g = f; + parse_file(init_str,f); + do_scores(); + p++; + } + if (!p) { + parse_file(init_str, ""); + do_scores(); + } + + return 0; +} + +String +find_file(String f) +{ + return path->find(f); +} + +/// make input file name: add default extension. "" is stdin. +void +destill_inname( String &name_str_r) +{ + if ( name_str_r.length_i() ) + { + if( name_str_r[ 0 ] != '-' ) + { + String a,b,c,d; + split_path(name_str_r,a,b,c,d); + + // add extension if not present. + if (d == "") + d = ".ly"; + name_str_r = a+b+c+d; + } + } else name_str_r = ""; +} + diff --git a/lily/meter-reg.cc b/lily/meter-reg.cc new file mode 100644 index 0000000000..a27737c076 --- /dev/null +++ b/lily/meter-reg.cc @@ -0,0 +1,64 @@ +/* + meter-reg.cc -- implement Meter_register + + source file of the LilyPond music typesetter + + (c) 1997 Han-Wen Nienhuys +*/ + +#include "meter-reg.hh" +#include "meter.hh" +#include "commandrequest.hh" + +Meter_register::Meter_register() + +{ + post_move_processing(); +} + +bool +Meter_register::try_request(Request*r_l) +{ + Command_req* creq_l= r_l->command(); + if (!creq_l || !creq_l->meterchange()) + return false; + + assert(!meter_req_l_); + meter_req_l_ = r_l->command()->meterchange(); + + return true; +} + +void +Meter_register::process_requests() +{ + if (meter_req_l_ ) { + Array args; + args.push(meter_req_l_->beats_i_); + args.push(meter_req_l_->one_beat_i_); + + meter_p_ = new Meter(args); + } + + if (meter_p_) + announce_element(Staff_elem_info(meter_p_, meter_req_l_) ); +} + +void +Meter_register::pre_move_processing() +{ + if (meter_p_) { + Meter * post_p =new Meter(*meter_p_); + Meter * pre_p =new Meter(*meter_p_); + + typeset_breakable_item(pre_p, meter_p_, post_p); + meter_p_ =0; + } +} + +void +Meter_register::post_move_processing() +{ + meter_req_l_ = 0; + meter_p_ =0; +} diff --git a/lily/meter.cc b/lily/meter.cc new file mode 100644 index 0000000000..94f6b6c5e9 --- /dev/null +++ b/lily/meter.cc @@ -0,0 +1,18 @@ +#include "scalar.hh" +#include "molecule.hh" +#include "meter.hh" +#include "paper-def.hh" +#include "lookup.hh" + +Meter::Meter(Arraya) + :args(a) +{ +} + +Molecule* +Meter::brew_molecule_p()const +{ + Symbol s = paper()->lookup_p_->meter(args); + return new Molecule(Atom(s)); +} + diff --git a/lily/misc.cc b/lily/misc.cc new file mode 100644 index 0000000000..093af7f0d4 --- /dev/null +++ b/lily/misc.cc @@ -0,0 +1,53 @@ +#include + +#include "item.hh" +#include "misc.hh" +#include "glob.hh" +#include "moment.hh" + + +// depreciated, see struct Duration* +Moment +wholes(int dur, int dots) +{ + if (!dur) + return 0; + + Moment f = Rational(1)/Moment(dur); + Moment delta = f; + + while (dots--) { + delta /= 2.0; + f += delta; + } + return f; +} +int +intlog2(int d) { + int i=0; + while (!(d&1)) { + d/= 2; + i++; + } + assert(!(d/2)); + return i; +} + +double +log_2(double x) { + return log(x) /log(2.0); +} + +Interval +itemlist_width(const Array &its) +{ + Interval iv ; + iv.set_empty(); + + for (int j =0; j < its.size(); j++){ + iv.unite (its[j]->width()); + + } + return iv; +} + diff --git a/lily/molecule.cc b/lily/molecule.cc new file mode 100644 index 0000000000..c52fdc7b32 --- /dev/null +++ b/lily/molecule.cc @@ -0,0 +1,146 @@ +#include "varray.hh" +#include "interval.hh" +#include "dimen.hh" +#include "string.hh" +#include "molecule.hh" +#include "symbol.hh" +#include "debug.hh" +#include "tex.hh" + +void +Atom::print() const +{ + mtor << "texstring: " < a; + a.push(print_dimen(off.y)); + a.push(print_dimen(off.x)); + a.push(sym.tex); + return substitute_args(s, a); +} + +/* *************** */ + +String +Molecule::TeXstring() const +{ + String s; + for(iter_top(ats,c); c.ok(); c++) + s+=c->TeXstring(); + return s; +} + +Box +Molecule::extent() const +{ + Box b; + for(iter_top(ats,c); c.ok(); c++) + b.unite(c->extent()); + return b; +} + +void +Molecule::translate(Offset o) +{ + for (iter_top(ats,c); c.ok(); c++) + c->translate(o); +} + +void +Molecule::add(const Molecule &m) +{ + for (iter_top(m.ats,c); c.ok(); c++) { + add(**c); + } +} + +void +Molecule::add_right(const Molecule &m) +{ + if (!ats.size()) { + add(m); + return; + } + Real xof=extent().x.right - m.extent().x.left; + Molecule toadd(m); + toadd.translate(Offset(xof, 0.0)); + add(toadd); +} + +void +Molecule::add_left(const Molecule &m) +{ + if (!ats.size()) { + add(m); + return; + } + Real xof=extent().x.left - m.extent().x.right; + Molecule toadd(m); + toadd.translate(Offset(xof, 0.0)); + add(toadd); +} + + +void +Molecule::add_top(const Molecule &m) +{ + if (!ats.size()) { + add(m); + return; + } + Real yof=extent().y.right - m.extent().y.left; + Molecule toadd(m); + toadd.translate(Offset(0,yof)); + add(toadd); +} + +void +Molecule::add_bottom(const Molecule &m) +{ + if (!ats.size()) { + add(m); + return; + } + Real yof=extent().y.left- m.extent().y.right; + Molecule toadd(m); + toadd.translate(Offset(0,yof)); + add(toadd); +} + +void +Molecule::operator = (const Molecule&) +{ + assert(false); +} + +Molecule::Molecule(const Molecule&s) +{ + add(s); +} + +void +Molecule::print() const +{ + for (iter_top(ats,c); c.ok(); c++) + c->print(); +} diff --git a/lily/mylexer.cc b/lily/mylexer.cc new file mode 100644 index 0000000000..7da6dddec8 --- /dev/null +++ b/lily/mylexer.cc @@ -0,0 +1,196 @@ +#include + +#include "interval.hh" +#include "identparent.hh" +#include "assoc-iter.hh" +#include "lexer.hh" +#include "input-file.hh" +#include "parser.hh" +#include "keyword.hh" +#include "assoc.hh" +#include "lexer.hh" +#include "debug.hh" +#include "notename.hh" +#include "source-file.hh" +#include "parseconstruct.hh" + +static Keyword_ent the_key_tab[]={ + "bar", BAR, + "cadenza", CADENZA, + "clef", CLEF, + "cm", CM_T, + "command", COMMAND, + "commands", COMMANDS, + "duration", DURATIONCOMMAND, + "geometric", GEOMETRIC, + "goto", GOTO, + "in", IN_T, + "key", KEY, + "meter", METER, + "midi", MIDI, + "mm", MM_T, + "multivoice", MULTIVOICE, + "octave", OCTAVECOMMAND, + "output", OUTPUT, + "partial", PARTIAL, + "paper", PAPER, + "plet", PLET, + "pt", PT_T, + "score", SCORE, + "script", SCRIPT, + "skip", SKIP, + "staff", STAFF, + "start", START_T, + "stem", STEM, + "table", TABLE, + "symboltables", SYMBOLTABLES, + "notenames", NOTENAMES, + "tempo", TEMPO, + "texid", TEXID, + "textstyle", TEXTSTYLE, + "unitspace", UNITSPACE, + "voice", VOICE, + "voices", VOICES, + "width", WIDTH, + "music", MUSIC, + "grouping", GROUPING, + 0,0 +}; + +int +My_flex_lexer::ret_notename(int *p, String text, int octave_mod) +{ + text = text.lower_str(); + char const* ch_c_l = here_ch_c_l(); + if ( ch_c_l ) { + ch_c_l--; + while ( ( *ch_c_l == ' ' ) + || ( *ch_c_l == '\t' ) || ( *ch_c_l == '\n' ) ) + ch_c_l--; + ch_c_l++; + } + + lookup_notename(p[0], p[1], text); + p[2] = octave_mod; + mtor << "notename: "<< text <; + defaulttab = 0; + errorlevel_i_ = 0; +} + +int +My_flex_lexer::lookup_keyword(String s) +{ + return keytable->lookup(s); +} + +Identifier* +My_flex_lexer::lookup_identifier(String s) +{ + if (!the_id_tab->elt_query(s)) + return 0; + + return (*the_id_tab)[s]; +} + +char const* +My_flex_lexer::here_ch_c_l() +{ + return include_stack.top()->sourcefile_l_->ch_c_l() + yyin->tellg(); +} + +void +My_flex_lexer::add_identifier(Identifier*i) +{ + delete lookup_identifier(i->name); + (*the_id_tab)[i->name] = i; +} + +My_flex_lexer::~My_flex_lexer() +{ + delete keytable; + delete defaulttab; + for (Assoc_iter ai(*the_id_tab); ai.ok(); ai++) { + mtor << "deleting: " << ai.key()<<'\n'; + delete ai.val(); + } + delete the_id_tab; +} +void +My_flex_lexer::print_declarations()const +{ + for (Assoc_iter ai(*the_id_tab); ai.ok(); ai++) { + ai.val()->print(); + } +} + +String +My_flex_lexer::spot()const +{ + return include_stack.top()->name + ": " + String( lineno() ); +} + +void +My_flex_lexer::LexerError(const char *s) +{ + if (lexer->include_stack.empty()) { + *mlog << "error at EOF" << s << '\n'; + } else { + char const* ch_c_l = here_ch_c_l(); + if ( ch_c_l ) { + ch_c_l--; + while ( ( *ch_c_l == ' ' ) || ( *ch_c_l == '\t' ) || ( *ch_c_l == '\n' ) ) + ch_c_l--; + ch_c_l++; + } + errorlevel_i_ |= 1; + error( s, ch_c_l ); + } +} + +// set the new input to s, remember old file. +void +My_flex_lexer::new_input(String s) +{ + if (!include_stack.empty()) { + include_stack.top()->line = lineno(); + // should this be saved at all? + include_stack.top()->defined_ch_c_l_ = defined_ch_c_l; + } + + Input_file *newin = new Input_file(s); + include_stack.push(newin); + switch_streams(newin->is); + + yylineno = 1; +} + +// pop the inputstack. +bool +My_flex_lexer::close_input() +{ + Input_file *old = include_stack.pop(); + bool ok = true; + if (include_stack.empty()) { + ok = false; + } else { + Input_file *i = include_stack.top(); + switch_streams(i->is); + yylineno = i->line; + defined_ch_c_l = i->defined_ch_c_l_; + } + delete old; + return ok; +} diff --git a/lily/note.cc b/lily/note.cc new file mode 100644 index 0000000000..496d892e5b --- /dev/null +++ b/lily/note.cc @@ -0,0 +1,321 @@ +/* + could use cleanup + */ +#include +#include "lexer.hh" +#include "string.hh" +#include "real.hh" +#include "debug.hh" +#include "musicalrequest.hh" +#include "commandrequest.hh" +#include "voice.hh" +#include "notename.hh" +#include "identparent.hh" +#include "varray.hh" +#include "text-def.hh" +#include "parseconstruct.hh" +#include "input-music.hh" +#include "voice-element.hh" + +int default_duration = 4, default_dots=0, default_octave=0; +int default_plet_type = 1, default_plet_dur = 1; +String textstyle="roman"; // in lexer? + +bool last_duration_mode = false; + +void +set_duration_mode(String s) +{ + s = s.upper_str(); + last_duration_mode = (s== "LAST"); +} + +void +last_duration(int n) +{ + if (last_duration_mode) + default_duration = n; +} + +/* triplet is '2/3' */ +void +set_plet(int num,int den) +{ + assert(num >0&& den>0); + default_plet_dur = num; + default_plet_type = den; +} + +Text_def* +get_text(String s) return t; +{ + t= new Text_def; + t->text_str_= s; + t->style_str_ = textstyle; + t->defined_ch_c_l_ = defined_ch_c_l; + return t; +} + +void +set_text_style(String s) +{ + textstyle = s; +} + +void +parse_octave (const char *a, int &j, int &oct) +{ + while (1) + { + if (a[j] == '\'') + oct ++; + else if (a[j] == '`') + oct --; + else + break; + j++; + } +} + +void +parse_pitch( const char *a, Melodic_req* mel_l) +{ + int j=0; + + // octave + mel_l->octave_i_ = default_octave; + parse_octave(a,j,mel_l->octave_i_); + + // accidental + mel_l->forceacc_b_ = false; + + if (a[j] == '!'){ + mel_l->forceacc_b_ = true; + j++; + } +} + +Voice_element * +get_note_element(String pitch, int * notename, int * duration ) +{ + Voice_element*v = new Voice_element; + v->defined_ch_c_l_ = defined_ch_c_l; + + + int dur = duration[0]; + int dots = duration[1]; + + if (dur >= 2) { + Stem_req * stem_req_p = new Stem_req(dur,dots); + stem_req_p->plet_factor = Moment(default_plet_dur, default_plet_type); + stem_req_p->defined_ch_c_l_ = defined_ch_c_l; + v->add(stem_req_p); + } + + if ( !defined_ch_c_l ) + defined_ch_c_l = lexer->here_ch_c_l(); + + Note_req * rq = new Note_req; + rq->notename_i_ =notename[0]; + rq->accidental_i_ = notename[1]; + parse_pitch(pitch, rq); + rq->octave_i_ += notename[2]; + + rq->balltype = dur; + rq->dots = dots; + rq->plet_factor = Moment(default_plet_dur, default_plet_type); + rq->defined_ch_c_l_ = defined_ch_c_l; + + v->add(rq); + + return v; +} + +Voice_element* +get_word_element(Text_def* tdef_p, int* duration) +{ + Voice_element* velt_p = new Voice_element; + velt_p->defined_ch_c_l_ = defined_ch_c_l; + + int dur = duration[0]; + int dots=duration[1]; + + tdef_p->defined_ch_c_l_ = defined_ch_c_l; + + Lyric_req* lreq_p = new Lyric_req(tdef_p); + + lreq_p->balltype = dur; + lreq_p->dots = dots; + lreq_p->plet_factor = Moment(default_plet_dur, default_plet_type); + lreq_p->print(); + lreq_p->defined_ch_c_l_ = defined_ch_c_l; + + velt_p->add(lreq_p); + + return velt_p; +} + +Voice_element * +get_rest_element(String, int * duration ) +{ + Voice_element* velt_p = new Voice_element; + velt_p->defined_ch_c_l_ = defined_ch_c_l; + + Rest_req * rest_req_p = new Rest_req; + rest_req_p->plet_factor = Moment(default_plet_dur, default_plet_type); + rest_req_p->balltype = duration[0]; + rest_req_p->dots = duration[1]; + rest_req_p->print(); + rest_req_p->defined_ch_c_l_ = defined_ch_c_l; + + velt_p->add(rest_req_p); + + return velt_p; +} + +void +get_default_duration(int *p) +{ + *p++ = default_duration; + *p = default_dots; +} + +void +set_default_duration(int *p) +{ + default_duration = *p++; + default_dots = *p++; +} + + +void +set_default_octave(String d) +{ + int i=0; + default_octave=0; + parse_octave(d, i, default_octave); +} + +Request* +get_plet_request( char c, int dur_i, int type_i ) +{ + Plet_req* plet_req_p = new Plet_req; + plet_req_p->dur_i_ = dur_i; + plet_req_p->type_i_ = type_i; + plet_req_p->type_c_ = c; + return plet_req_p; +} + +Request* +get_request(char c) +{ + Request* req_p=0; + switch (c) { + case '|': + req_p = new Barcheck_req; + break; + + case '[': + case ']': + { + Beam_req*b = new Beam_req; + if (default_plet_type != 1) + b->nplet = default_plet_type; + req_p = b; + } + break; + + + case ')': + case '(': + req_p = new Slur_req; + break; + default: + assert(false); + break; + } + + switch (c) { + case '(': + case '[': + req_p->span()->spantype = Span_req::START; + break; + case ')': + case ']': + req_p->span()->spantype = Span_req::STOP; + break; + + default: + break; + } + + req_p->defined_ch_c_l_ = req_defined_ch_c_l; + return req_p; +} + +void +add_requests(Voice_element *v, Array &req) +{ + for (int i = 0; i < req.size(); i++) { + v->add(req[i]); + } + req.set_size(0); +} + +Script_def* +get_scriptdef(char c) +{ + String s; + switch (c) { + case '^' : s = "marcato"; + break; + case '+' : s = "stopped"; + break; + case '-' : s = "tenuto"; + break; + case '|': s = "staccatissimo"; + break; + case 'o' : s = ""; + break; + case '>' : s = "accent"; + break; + case 'v' : s = ""; + break; + case '.' : s = "staccato"; + break; + } + return lexer->lookup_identifier(s)->script(1); +} + +Request* +get_script_req(int d , Script_def*def) +{ + Script_req* script_req_p = new Script_req(d, def); + return script_req_p; +} + +Request* +get_text_req(int d , Text_def*def) +{ + Text_req* text_req_p = new Text_req(d, def); + return text_req_p; +} + +Request* +get_stemdir_req(int d) +{ + Group_feature_req * gfreq_p = new Group_feature_req; + gfreq_p->stemdir_i_ =d; + return gfreq_p; +} + +Request* +get_grouping_req(Array i_arr) +{ + Measure_grouping_req * mr_p = new Measure_grouping_req; + for (int i=0; i beat_i_arr_.push(i_arr[i++]); + mr_p->elt_length_arr_.push(Moment(1, i_arr[i++])); + } + return mr_p; +} diff --git a/lily/notehead.cc b/lily/notehead.cc new file mode 100644 index 0000000000..722b231e68 --- /dev/null +++ b/lily/notehead.cc @@ -0,0 +1,77 @@ +#include "misc.hh" +#include "notehead.hh" +#include "dimen.hh" +#include "debug.hh" +#include "paper-def.hh" +#include "lookup.hh" +#include "molecule.hh" +#include "musicalrequest.hh" + + + +Notehead::Notehead(int ss) +{ + x_dir = 0; + staff_size=ss; + position = 0; + balltype = 0; + dots = 0; + extremal = 0; +} + +void +Notehead::set_rhythmic(Rhythmic_req*r_req_l) +{ + balltype = r_req_l->balltype; + dots = r_req_l->dots; +} + +void +Notehead::do_print()const +{ +#ifndef NPRINT + mtor << "balltype "<< balltype << ", position = "<< position + << "dots " << dots; +#endif +} + + +int +Notehead::compare(Notehead *const &a, Notehead * const &b) +{ + return a->position - b->position; +} + +Molecule* +Notehead::brew_molecule_p() const return out; +{ + Paper_def *p = paper(); + + Real dy = p->internote(); + Symbol s = p->lookup_p_->ball(balltype); + + out = new Molecule(Atom(s)); + if (dots) { + Symbol d = p->lookup_p_->dots(dots); + Molecule dm; + dm.add(Atom(d)); + if (!(position %2)) + dm.translate(Offset(0,dy)); + out->add_right(dm); + } + out->translate(Offset(x_dir * p->note_width(),0)); + bool streepjes = (position<-1)||(position > staff_size+1); + if (streepjes) { + int dir = sign(position); + int s =(position<-1) ? -((-position)/2): (position-staff_size)/2; + Symbol str = p->lookup_p_->streepjes(s); + Molecule sm; + sm.add(Atom(str)); + if (position % 2) + sm.translate(Offset(0,-dy* dir)); + out->add(sm); + } + + out->translate(Offset(0,dy*position)); +} + diff --git a/lily/notename.cc b/lily/notename.cc new file mode 100644 index 0000000000..e6d62644b2 --- /dev/null +++ b/lily/notename.cc @@ -0,0 +1,47 @@ +#include "glob.hh" +#include "string.hh" +#include "notename.hh" +#include "lexer.hh" +#include "identifier.hh" + + + +void +Notename_tab::lookup(int &large, int &small, String s) +{ + large = -1; + small = 0; + + for (int i =0; i < 7*5; i++) + if (s == notetab[i]) + { + large = i /5; + small = i %5 - 2; + return; + } +} + + +void +Notename_tab::set(int l, int s, String n) +{ + assert(l < 8 && s <= 2 && s >= -2 && l >=0); + notetab[l * 5 + s +2] = n; +} +/* *************** */ +void +My_flex_lexer::set(Notename_tab *n) +{ + delete defaulttab; + defaulttab = n; +} + +void +My_flex_lexer::lookup_notename(int &large, int &small, String s) +{ + if (!defaulttab) + set(lookup_identifier("default_table")-> + notename_tab(true)); + + defaulttab->lookup(large, small, s); +} diff --git a/lily/paper-def.cc b/lily/paper-def.cc new file mode 100644 index 0000000000..b49a53fc8e --- /dev/null +++ b/lily/paper-def.cc @@ -0,0 +1,91 @@ +#include +#include "misc.hh" +#include "paper-def.hh" +#include "debug.hh" +#include "lookup.hh" +#include "dimen.hh" + + + +// golden ratio +const Real PHI = (1+sqrt(5))/2; + +// see Roelofs, p. 57 +Real +Paper_def::duration_to_dist(Moment d) +{ + if (!d) + return 0; + + return whole_width * pow(geometric_, log_2(d)); +} + +Real +Paper_def::rule_thickness()const +{ + return 0.4 PT; +} + +Paper_def::Paper_def(Lookup *l) +{ + lookup_p_ = l; + linewidth = 15 *CM_TO_PT; // in cm for now + whole_width = 8 * note_width(); + geometric_ = sqrt(2); + outfile = "lelie.out"; +} + +Paper_def::~Paper_def() +{ + delete lookup_p_; +} +Paper_def::Paper_def(Paper_def const&s) +{ + lookup_p_ = new Lookup(*s.lookup_p_); + geometric_ = s.geometric_; + whole_width = s.whole_width; + outfile = s.outfile; + linewidth = s.linewidth; +} + +void +Paper_def::set(Lookup*l) +{ + assert(l != lookup_p_); + delete lookup_p_; + lookup_p_ = l; +} + +Real +Paper_def::interline() const +{ + return lookup_p_->ball(4).dim.y.length(); +} + +Real +Paper_def::internote() const +{ + return lookup_p_->internote(); +} +Real +Paper_def::note_width()const +{ + return lookup_p_->ball(4).dim.x.length( ); +} +Real +Paper_def::standard_height() const +{ + return 20 PT; +} + +void +Paper_def::print() const +{ +#ifndef NPRINT + mtor << "Paper {width: " << print_dimen(linewidth); + mtor << "whole: " << print_dimen(whole_width); + mtor << "out: " <print(); + mtor << "}\n"; +#endif +} diff --git a/lily/parser.y b/lily/parser.y new file mode 100644 index 0000000000..ba9703e4b8 --- /dev/null +++ b/lily/parser.y @@ -0,0 +1,828 @@ +%{ // -*-Fundamental-*- +#include + +#include "lookup.hh" +#include "misc.hh" +#include "lexer.hh" +#include "paper-def.hh" +#include "midi-def.hh" +#include "input-score.hh" +#include "main.hh" +#include "keyword.hh" +#include "debug.hh" +#include "parseconstruct.hh" +#include "dimen.hh" +#include "identifier.hh" +#include "commandrequest.hh" +#include "musicalrequest.hh" +#include "voice-element.hh" + +#ifndef NDEBUG +#define YYDEBUG 1 +#endif + +Array pre_reqs, post_reqs; +Array define_spots; +Paper_def*default_paper(); +char const* defined_ch_c_l; +char const* req_defined_ch_c_l; +int fatal_error_i = 0; + +%} + + +%union { + Request * request; + Real real; + Identifier *id; + Voice *voice; + Voice_element *el; + String *string; + const char *consstr; + Paper_def *paper; + Midi_def* midi; + Input_music *music; + Music_general_chord *chord; + Music_voice *mvoice; + int i; + char c; + int ii[10]; + Moment *moment; + + Array * strvec; + Array *intvec; + Array *melreqvec; + Input_staff *staff; + Input_score *score; + Symtables * symtables; + Symtable * symtable; + Symbol * symbol; + Lookup*lookup; + Interval *interval; + Box *box; + Notename_tab *notename_tab; + Script_def * script; + Text_def * textdef; +} + +%token VOICE STAFF SCORE TITLE BAR OUTPUT MULTIVOICE +%token CM_T IN_T PT_T MM_T PAPER WIDTH METER UNITSPACE SKIP COMMANDS COMMAND +%token GEOMETRIC START_T DURATIONCOMMAND OCTAVECOMMAND +%token KEY CLEF TABLE VOICES STEM +%token PARTIAL MUSIC GROUPING CADENZA +%token END SYMBOLTABLES TEXID TABLE NOTENAMES SCRIPT TEXTSTYLE PLET +%token GOTO +%token MIDI TEMPO + +%token IDENTIFIER +%token PITCHMOD DURATION RESTNAME +%token NOTENAME +%token REAL +%token STRING + +%token DOTS INT +%type unit +%type pitch_list +%type open_request_parens close_request_parens close_plet_parens +%type declaration +%type declarable_identifier +%type paper_block paper_body +%type midi_block midi_body +%type dim real +%type default_duration explicit_duration notemode_duration mudela_duration +%type notename +%type duration_length +%type voice_elt full_element lyrics_elt command_elt + +%type score_block score_body +%type staff_block staff_init staff_body +%type int +%type intastint_list +%type post_request pre_request command_req +%type pitchmod +%type music +%type music_chord music_chord_body + +%type music_voice_body music_voice + +%type dinterval +%type box +%type symtable symtable_body +%type symtables symtables_body +%type symboldef +%type notename_tab notename_tab_body +%type script_dir +%type