From 06c37d59e18df1ca341b114707f54a1326301e5d Mon Sep 17 00:00:00 2001 From: Corwin Perren Date: Fri, 8 Jun 2018 00:50:59 -0700 Subject: [PATCH] Added OS II assignments --- .../Concurrency 1/main.c | 170 + .../Concurrency 1/makefile | 8 + .../Concurrency 1/mt19937ar.h | 190 + .../Concurrency 1/readme.txt | 5 + .../Concurrency 2/main.c | 186 + .../Concurrency 2/makefile | 8 + .../Concurrency 2/mt19937ar.h | 190 + .../Concurrency 2/readme.txt | 5 + .../Concurrency 3/makefile | 9 + .../Concurrency 3/mt19937ar.h | 190 + .../Concurrency 3/problem1.c | 172 + .../Concurrency 3/problem2.c | 339 + .../Concurrency 3/readme.txt | 6 + .../Concurrency 4/main.c | 262 + .../Concurrency 4/makefile | 8 + .../Concurrency 4/mt19937ar.h | 190 + .../Concurrency 4/readme.txt | 11 + .../Project 1/CS444_project1_4.pdf | Bin 0 -> 83371 bytes .../Kernel Assignments/Project 1/IEEEtran.cls | 6347 ++++++++++++ .../Project 1/IEEEtranN.bst | 2735 +++++ .../Kernel Assignments/Project 1/commands.tex | 15 + .../Kernel Assignments/Project 1/flags.tex | 53 + .../Project 1/homework1.tex | 107 + .../Kernel Assignments/Project 1/latexmk.pl | 8802 +++++++++++++++++ .../Kernel Assignments/Project 1/latexmkrc | 31 + .../Kernel Assignments/Project 1/makefile | 19 + .../Project 1/questions.tex | 12 + .../Project 1/versioncontrollog.tex | 10 + .../Kernel Assignments/Project 1/worklog.tex | 11 + .../Kernel Assignments/Project 2/IEEEtran.cls | 6347 ++++++++++++ .../Project 2/IEEEtranN.bst | 2735 +++++ .../Kernel Assignments/Project 2/design.tex | 27 + .../Project 2/homework2.patch | 278 + .../Project 2/homework2.tex | 105 + .../Kernel Assignments/Project 2/io_test.py | 41 + .../Kernel Assignments/Project 2/latexmk.pl | 8802 +++++++++++++++++ .../Kernel Assignments/Project 2/latexmkrc | 31 + .../Kernel Assignments/Project 2/makefile | 19 + .../Project 2/questions.tex | 19 + .../Project 2/versioncontrollog.tex | 15 + .../Kernel Assignments/Project 2/worklog.tex | 17 + .../Kernel Assignments/Project 3/IEEEtran.cls | 6347 ++++++++++++ .../Kernel Assignments/Project 3/design.tex | 22 + .../Project 3/homework3.patch | 254 + .../Project 3/homework3.tex | 98 + .../Kernel Assignments/Project 3/latexmk.pl | 8802 +++++++++++++++++ .../Kernel Assignments/Project 3/latexmkrc | 31 + .../Kernel Assignments/Project 3/makefile | 19 + .../Project 3/questions.tex | 17 + .../Project 3/versioncontrollog.tex | 8 + .../Kernel Assignments/Project 3/worklog.tex | 14 + .../Kernel Assignments/Project 4/IEEEtran.cls | 6347 ++++++++++++ .../Kernel Assignments/Project 4/design.tex | 38 + .../Project 4/find_fragmentation.c | 18 + .../Project 4/homework4.patch | 410 + .../Project 4/homework4.tex | 99 + .../Kernel Assignments/Project 4/latexmk.pl | 8802 +++++++++++++++++ .../Kernel Assignments/Project 4/latexmkrc | 31 + .../Kernel Assignments/Project 4/makefile | 19 + .../Project 4/questions.tex | 44 + .../Project 4/versioncontrollog.tex | 11 + .../Kernel Assignments/Project 4/worklog.tex | 20 + .../Writing 1/IEEEtran.cls | 6347 ++++++++++++ .../Writing 1/IEEEtranN.bst | 2735 +++++ .../Writing Assignments/Writing 1/latexmk.pl | 8802 +++++++++++++++++ .../Writing Assignments/Writing 1/latexmkrc | 31 + .../Writing Assignments/Writing 1/makefile | 19 + .../Writing Assignments/Writing 1/output.tex | 92 + .../Writing Assignments/Writing 1/writing.tex | 81 + .../Writing 2/IEEEtran.cls | 6347 ++++++++++++ .../Writing Assignments/Writing 2/latexmk.pl | 8802 +++++++++++++++++ .../Writing Assignments/Writing 2/latexmkrc | 31 + .../Writing Assignments/Writing 2/makefile | 19 + .../Writing Assignments/Writing 2/output.tex | 92 + .../Writing 2/writing/writing.tex | 17 + .../Writing 2/writing2_perrenc.pdf | Bin 0 -> 40386 bytes 76 files changed, 103393 insertions(+) create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Concurrency Assignments/Concurrency 1/main.c create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Concurrency Assignments/Concurrency 1/makefile create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Concurrency Assignments/Concurrency 1/mt19937ar.h create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Concurrency Assignments/Concurrency 1/readme.txt create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Concurrency Assignments/Concurrency 2/main.c create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Concurrency Assignments/Concurrency 2/makefile create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Concurrency Assignments/Concurrency 2/mt19937ar.h create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Concurrency Assignments/Concurrency 2/readme.txt create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Concurrency Assignments/Concurrency 3/makefile create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Concurrency Assignments/Concurrency 3/mt19937ar.h create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Concurrency Assignments/Concurrency 3/problem1.c create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Concurrency Assignments/Concurrency 3/problem2.c create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Concurrency Assignments/Concurrency 3/readme.txt create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Concurrency Assignments/Concurrency 4/main.c create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Concurrency Assignments/Concurrency 4/makefile create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Concurrency Assignments/Concurrency 4/mt19937ar.h create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Concurrency Assignments/Concurrency 4/readme.txt create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Kernel Assignments/Project 1/CS444_project1_4.pdf create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Kernel Assignments/Project 1/IEEEtran.cls create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Kernel Assignments/Project 1/IEEEtranN.bst create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Kernel Assignments/Project 1/commands.tex create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Kernel Assignments/Project 1/flags.tex create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Kernel Assignments/Project 1/homework1.tex create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Kernel Assignments/Project 1/latexmk.pl create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Kernel Assignments/Project 1/latexmkrc create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Kernel Assignments/Project 1/makefile create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Kernel Assignments/Project 1/questions.tex create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Kernel Assignments/Project 1/versioncontrollog.tex create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Kernel Assignments/Project 1/worklog.tex create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Kernel Assignments/Project 2/IEEEtran.cls create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Kernel Assignments/Project 2/IEEEtranN.bst create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Kernel Assignments/Project 2/design.tex create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Kernel Assignments/Project 2/homework2.patch create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Kernel Assignments/Project 2/homework2.tex create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Kernel Assignments/Project 2/io_test.py create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Kernel Assignments/Project 2/latexmk.pl create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Kernel Assignments/Project 2/latexmkrc create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Kernel Assignments/Project 2/makefile create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Kernel Assignments/Project 2/questions.tex create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Kernel Assignments/Project 2/versioncontrollog.tex create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Kernel Assignments/Project 2/worklog.tex create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Kernel Assignments/Project 3/IEEEtran.cls create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Kernel Assignments/Project 3/design.tex create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Kernel Assignments/Project 3/homework3.patch create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Kernel Assignments/Project 3/homework3.tex create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Kernel Assignments/Project 3/latexmk.pl create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Kernel Assignments/Project 3/latexmkrc create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Kernel Assignments/Project 3/makefile create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Kernel Assignments/Project 3/questions.tex create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Kernel Assignments/Project 3/versioncontrollog.tex create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Kernel Assignments/Project 3/worklog.tex create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Kernel Assignments/Project 4/IEEEtran.cls create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Kernel Assignments/Project 4/design.tex create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Kernel Assignments/Project 4/find_fragmentation.c create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Kernel Assignments/Project 4/homework4.patch create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Kernel Assignments/Project 4/homework4.tex create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Kernel Assignments/Project 4/latexmk.pl create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Kernel Assignments/Project 4/latexmkrc create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Kernel Assignments/Project 4/makefile create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Kernel Assignments/Project 4/questions.tex create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Kernel Assignments/Project 4/versioncontrollog.tex create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Kernel Assignments/Project 4/worklog.tex create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Writing Assignments/Writing 1/IEEEtran.cls create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Writing Assignments/Writing 1/IEEEtranN.bst create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Writing Assignments/Writing 1/latexmk.pl create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Writing Assignments/Writing 1/latexmkrc create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Writing Assignments/Writing 1/makefile create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Writing Assignments/Writing 1/output.tex create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Writing Assignments/Writing 1/writing.tex create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Writing Assignments/Writing 2/IEEEtran.cls create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Writing Assignments/Writing 2/latexmk.pl create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Writing Assignments/Writing 2/latexmkrc create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Writing Assignments/Writing 2/makefile create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Writing Assignments/Writing 2/output.tex create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Writing Assignments/Writing 2/writing/writing.tex create mode 100644 OSU Coursework/CS 444 - Operating Systems II/Writing Assignments/Writing 2/writing2_perrenc.pdf diff --git a/OSU Coursework/CS 444 - Operating Systems II/Concurrency Assignments/Concurrency 1/main.c b/OSU Coursework/CS 444 - Operating Systems II/Concurrency Assignments/Concurrency 1/main.c new file mode 100644 index 0000000..9e99901 --- /dev/null +++ b/OSU Coursework/CS 444 - Operating Systems II/Concurrency Assignments/Concurrency 1/main.c @@ -0,0 +1,170 @@ +/* + * File: main.c + * Author: caperren + * + * Created on April 13, 2018, 7:27 PM + */ + +/* + * Important implementation notes... + * Consumer prints out number in struct on consumption + * Timeout is how long before consumer is done with item (2-7 seconds) + * Producer waits 3-7 seconds + * Max buffer size is 32 + * Consumer/s and producer need lock on buffer when doing things + * If nothing in queue, consumer blocks until there is + */ + +#include "mt19937ar.h" + +#include +#include +#include +#include +#include +#include + +// Program defines you might want to change +#define MAX_BUFFER_SIZE 32 + +#define MIN_RANDOM_PRODUCER 3 +#define MAX_RANDOM_PRODUCER 7 + +#define MIN_RANDOM_CONSUMER 2 +#define MAX_RANDOM_CONSUMER 9 + +//RDRAND value to check for +#define RDRAND_FLAG (1 << 30) + +// Data structure for the buffer elements +struct two_values { + uint8_t number; + uint8_t work_timeout; +}; + +//Storage containers and mutex for access +struct two_values storage_buffer[MAX_BUFFER_SIZE]; +uint16_t tasks_in_buffer = 0; + +pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + +// Get random number based on whether rdrand is supported. +uint8_t get_random_number(uint8_t min, uint8_t max) { + uint8_t rand_val; + unsigned long seed; + + unsigned int eax; + unsigned int ebx; + unsigned int ecx; + unsigned int edx; + + eax = 0x01; + + // ASM for checking if RDRAND supported + __asm__ __volatile__("cpuid" + : "=a" (eax), + "=b" (ebx), + "=c" (ecx), + "=d" (edx) + : "a" (1), + "c" (0) + ); + + // Seed random with /dev/random + int random = open("/dev/random", O_RDONLY); + read(random, &seed, sizeof (seed)); + + unsigned int random_value; + + if ((ecx & RDRAND_FLAG) == RDRAND_FLAG) { + char return_code = 0; + char count = 0; + + // ASM for RDRAND + while(return_code != 1 && count < 10){ + __asm__ volatile( + "rdrand %0 ; setc %1" + : "=r" (random_value), "=qm" (return_code) + ); + + count++; + } + } else { + // Twister if RDRAND not supported + init_genrand(seed); + random_value = genrand_int32(); + } + + return (random_value % (max + 1 - min)) + min; +} + +void *consume_buffer_items(){ + uint8_t number; + uint8_t work_timeout; + + while(1){ + // This waits for a task to exist, then makes a temporary copy + // of the data in the last item in the queue. + // It then removes the item, while mutex locking during all of this + while(tasks_in_buffer == 0); + pthread_mutex_lock(&mutex); + + number = storage_buffer[tasks_in_buffer - 1].number; + work_timeout = storage_buffer[tasks_in_buffer - 1].work_timeout; + storage_buffer[tasks_in_buffer - 1].number = 0; + storage_buffer[tasks_in_buffer - 1].work_timeout = 0; + tasks_in_buffer--; + + pthread_mutex_unlock(&mutex); + + printf("Consumer found number: %u. Now waiting %u seconds.\n", number, work_timeout); + fflush(stdout); + + sleep(work_timeout); + } + +} + +int main(int argc, char **argv) { + pthread_t consumer_thread; + + // This makes the consumer thread + if(pthread_create(&consumer_thread, NULL, consume_buffer_items, NULL)) { + fprintf(stderr, "Error creating thread\n"); + return 1; + } + + //Zero out array + for(uint16_t i = 0 ; i < MAX_BUFFER_SIZE ; i++){ + storage_buffer[i].number = 0; + storage_buffer[i].work_timeout = 0; + } + + uint8_t number; + uint8_t work_timeout; + uint8_t producer_sleep; + + while(1){ + // This generates values for a new buffer element, waits until theres + // space in the buffer, then adds and item to the buffer + number = get_random_number(0, UINT8_MAX); + work_timeout = get_random_number(MIN_RANDOM_CONSUMER, MAX_RANDOM_CONSUMER); + producer_sleep = get_random_number(MIN_RANDOM_PRODUCER, MAX_RANDOM_PRODUCER); + + while(tasks_in_buffer == MAX_BUFFER_SIZE); + + pthread_mutex_lock(&mutex); + storage_buffer[tasks_in_buffer].number = number; + storage_buffer[tasks_in_buffer].work_timeout = work_timeout; + tasks_in_buffer++; + pthread_mutex_unlock(&mutex); + + printf("Producer adding number: %u. Consumers's delay will be %u seconds. Producer waiting %u seconds.\n", number, work_timeout, producer_sleep); + fflush(stdout); + + sleep(producer_sleep); + } + + return 0; +} + diff --git a/OSU Coursework/CS 444 - Operating Systems II/Concurrency Assignments/Concurrency 1/makefile b/OSU Coursework/CS 444 - Operating Systems II/Concurrency Assignments/Concurrency 1/makefile new file mode 100644 index 0000000..ecd054f --- /dev/null +++ b/OSU Coursework/CS 444 - Operating Systems II/Concurrency Assignments/Concurrency 1/makefile @@ -0,0 +1,8 @@ +all: clean build + +clean: + rm -f *.o + rm -f concurrency1 + +build: + gcc main.c mt19937ar.h -o concurrency1 -std=c99 -pthread \ No newline at end of file diff --git a/OSU Coursework/CS 444 - Operating Systems II/Concurrency Assignments/Concurrency 1/mt19937ar.h b/OSU Coursework/CS 444 - Operating Systems II/Concurrency Assignments/Concurrency 1/mt19937ar.h new file mode 100644 index 0000000..0c18485 --- /dev/null +++ b/OSU Coursework/CS 444 - Operating Systems II/Concurrency Assignments/Concurrency 1/mt19937ar.h @@ -0,0 +1,190 @@ +/* + A C-program for MT19937, with initialization improved 2002/1/26. + Coded by Takuji Nishimura and Makoto Matsumoto. + + Before using, initialize the state by using init_genrand(seed) + or init_by_array(init_key, key_length). + + Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. The names of its contributors may not be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + + Any feedback is very welcome. + http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html + email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space) +*/ + +#include + +/* Period parameters */ +#define N 624 +#define M 397 +#define MATRIX_A 0x9908b0dfUL /* constant vector a */ +#define UPPER_MASK 0x80000000UL /* most significant w-r bits */ +#define LOWER_MASK 0x7fffffffUL /* least significant r bits */ + +static unsigned long mt[N]; /* the array for the state vector */ +static int mti=N+1; /* mti==N+1 means mt[N] is not initialized */ + +/* initializes mt[N] with a seed */ +void init_genrand(unsigned long s) +{ + mt[0]= s & 0xffffffffUL; + for (mti=1; mti> 30)) + mti); + /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */ + /* In the previous versions, MSBs of the seed affect */ + /* only MSBs of the array mt[]. */ + /* 2002/01/09 modified by Makoto Matsumoto */ + mt[mti] &= 0xffffffffUL; + /* for >32 bit machines */ + } +} + +/* initialize by an array with array-length */ +/* init_key is the array for initializing keys */ +/* key_length is its length */ +/* slight change for C++, 2004/2/26 */ +void init_by_array(unsigned long init_key[], int key_length) +{ + int i, j, k; + init_genrand(19650218UL); + i=1; j=0; + k = (N>key_length ? N : key_length); + for (; k; k--) { + mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1664525UL)) + + init_key[j] + j; /* non linear */ + mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */ + i++; j++; + if (i>=N) { mt[0] = mt[N-1]; i=1; } + if (j>=key_length) j=0; + } + for (k=N-1; k; k--) { + mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1566083941UL)) + - i; /* non linear */ + mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */ + i++; + if (i>=N) { mt[0] = mt[N-1]; i=1; } + } + + mt[0] = 0x80000000UL; /* MSB is 1; assuring non-zero initial array */ +} + +/* generates a random number on [0,0xffffffff]-interval */ +unsigned long genrand_int32(void) +{ + unsigned long y; + static unsigned long mag01[2]={0x0UL, MATRIX_A}; + /* mag01[x] = x * MATRIX_A for x=0,1 */ + + if (mti >= N) { /* generate N words at one time */ + int kk; + + if (mti == N+1) /* if init_genrand() has not been called, */ + init_genrand(5489UL); /* a default initial seed is used */ + + for (kk=0;kk> 1) ^ mag01[y & 0x1UL]; + } + for (;kk> 1) ^ mag01[y & 0x1UL]; + } + y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK); + mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1UL]; + + mti = 0; + } + + y = mt[mti++]; + + /* Tempering */ + y ^= (y >> 11); + y ^= (y << 7) & 0x9d2c5680UL; + y ^= (y << 15) & 0xefc60000UL; + y ^= (y >> 18); + + return y; +} + +/* generates a random number on [0,0x7fffffff]-interval */ +long genrand_int31(void) +{ + return (long)(genrand_int32()>>1); +} + +/* generates a random number on [0,1]-real-interval */ +double genrand_real1(void) +{ + return genrand_int32()*(1.0/4294967295.0); + /* divided by 2^32-1 */ +} + +/* generates a random number on [0,1)-real-interval */ +double genrand_real2(void) +{ + return genrand_int32()*(1.0/4294967296.0); + /* divided by 2^32 */ +} + +/* generates a random number on (0,1)-real-interval */ +double genrand_real3(void) +{ + return (((double)genrand_int32()) + 0.5)*(1.0/4294967296.0); + /* divided by 2^32 */ +} + +/* generates a random number on [0,1) with 53-bit resolution*/ +double genrand_res53(void) +{ + unsigned long a=genrand_int32()>>5, b=genrand_int32()>>6; + return(a*67108864.0+b)*(1.0/9007199254740992.0); +} +/* These real versions are due to Isaku Wada, 2002/01/09 added */ + +//int main(void) +//{ +// int i; +// unsigned long init[4]={0x123, 0x234, 0x345, 0x456}, length=4; +// init_by_array(init, length); +// printf("1000 outputs of genrand_int32()\n"); +// for (i=0; i<1000; i++) { +// printf("%10lu ", genrand_int32()); +// if (i%5==4) printf("\n"); +// } +// printf("\n1000 outputs of genrand_real2()\n"); +// for (i=0; i<1000; i++) { +// printf("%10.8f ", genrand_real2()); +// if (i%5==4) printf("\n"); +// } +// return 0; +//} diff --git a/OSU Coursework/CS 444 - Operating Systems II/Concurrency Assignments/Concurrency 1/readme.txt b/OSU Coursework/CS 444 - Operating Systems II/Concurrency Assignments/Concurrency 1/readme.txt new file mode 100644 index 0000000..1897a99 --- /dev/null +++ b/OSU Coursework/CS 444 - Operating Systems II/Concurrency Assignments/Concurrency 1/readme.txt @@ -0,0 +1,5 @@ +Corwin Perren - Concurrency HW 1 + +To make this program on the os server, cd into this directory and run "make". + +To run the program, type "./concurrency1" into the terminal and hit enter. \ No newline at end of file diff --git a/OSU Coursework/CS 444 - Operating Systems II/Concurrency Assignments/Concurrency 2/main.c b/OSU Coursework/CS 444 - Operating Systems II/Concurrency Assignments/Concurrency 2/main.c new file mode 100644 index 0000000..7b62c03 --- /dev/null +++ b/OSU Coursework/CS 444 - Operating Systems II/Concurrency Assignments/Concurrency 2/main.c @@ -0,0 +1,186 @@ +/* + * File: main.c + * Author: caperren + * + * Created on April 27th, 2018 + */ + +#include "mt19937ar.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Program defines you might want to change +#define NUM_PHILOSOPHERS 5 + +#define MIN_RANDOM_EAT 2 +#define MAX_RANDOM_EAT 9 + +#define MIN_RANDOM_THINK 1 +#define MAX_RANDOM_THINK 20 + +uint8_t* philosopher_names[] = { + "Plato", + "Aristotle", + "Socrates", + "Confucius", + "Voltaire" +}; + +//RDRAND value to check for +#define RDRAND_FLAG (1 << 30) + +sem_t fork_semaphores[NUM_PHILOSOPHERS]; +uint32_t philosopher_eat_counts[NUM_PHILOSOPHERS]; + +// Get random number based on whether rdrand is supported. +uint8_t get_random_number(uint8_t min, uint8_t max) { + uint8_t rand_val; + unsigned long seed; + + unsigned int eax; + unsigned int ebx; + unsigned int ecx; + unsigned int edx; + + eax = 0x01; + + // ASM for checking if RDRAND supported + __asm__ __volatile__("cpuid" + : "=a" (eax), + "=b" (ebx), + "=c" (ecx), + "=d" (edx) + : "a" (1), + "c" (0) + ); + + // Seed random with /dev/random + int random = open("/dev/random", O_RDONLY); + read(random, &seed, sizeof (seed)); + + unsigned int random_value; + + if ((ecx & RDRAND_FLAG) == RDRAND_FLAG) { + char return_code = 0; + char count = 0; + + // ASM for RDRAND + while(return_code != 1 && count < 10){ + __asm__ volatile( + "rdrand %0 ; setc %1" + : "=r" (random_value), "=qm" (return_code) + ); + + count++; + } + } else { + // Twister if RDRAND not supported + init_genrand(seed); + random_value = genrand_int32(); + } + + return (random_value % (max + 1 - min)) + min; +} + +void think(uint8_t *name){ + uint8_t random = get_random_number(MIN_RANDOM_THINK, MAX_RANDOM_THINK); + + printf("%s thinking for %u seconds.\n", name, random); + fflush(stdout); + + sleep(random); +} + +void eat(uint8_t *name){ + uint8_t random = get_random_number(MIN_RANDOM_EAT, MAX_RANDOM_EAT); + + printf("%s eating for %u seconds.\n", name, random); + fflush(stdout); + + sleep(random); +} + +void *philosopher(void *number){ + // Store values that will be useful as the thread runs + uint16_t philosophers_number = *((uint16_t *) number); + uint16_t philosophers_number_plus_one = philosophers_number + 1; + uint16_t fork_num_plus_one = philosophers_number_plus_one % NUM_PHILOSOPHERS; + + while(1){ + // Think + think(philosopher_names[philosophers_number]); + + // Get forks + printf("%s waiting for forks %u and %u.\n", philosopher_names[philosophers_number], philosophers_number, fork_num_plus_one); + fflush(stdout); + + sem_wait(&fork_semaphores[MIN(philosophers_number, fork_num_plus_one)]); + sem_wait(&fork_semaphores[MAX(philosophers_number, fork_num_plus_one)]); + + printf("%s now has forks %u and %u.\n", philosopher_names[philosophers_number], philosophers_number, fork_num_plus_one); + fflush(stdout); + + // Eat + eat(philosopher_names[philosophers_number]); + philosopher_eat_counts[philosophers_number]++; + + // Release forks + printf("%s releasing forks %u and %u.\n", philosopher_names[philosophers_number], philosophers_number, fork_num_plus_one); + fflush(stdout); + + sem_post(&fork_semaphores[philosophers_number]); + sem_post(&fork_semaphores[fork_num_plus_one]); + + } + +} + +int main(int argc, char **argv) { + // Containers to hold our threads, and the philosopher index + pthread_t consumer_threads[NUM_PHILOSOPHERS]; + uint16_t philosophers_numbers[NUM_PHILOSOPHERS]; + + // Initialize semaphores, and arrays used to keep track of things + for(uint16_t i = 0 ; i < NUM_PHILOSOPHERS ; i++){ + sem_init(&fork_semaphores[i], 0, 1); + philosophers_numbers[i] = i; + philosopher_eat_counts[i] = 0; + } + + // Create all the philosopher threads + for(uint16_t i = 0 ; i < NUM_PHILOSOPHERS ; i++){ + if(pthread_create(&consumer_threads[i], NULL, philosopher, &philosophers_numbers[i])) { + fprintf(stderr, "Error creating thread\n"); + return 1; + } + } + + // This monitoring while loop prints our the eating counts of the + // philosophers so you can easily see how often they've ate without + // having to dig through the text output. It runs once every five seconds. + while(1){ + sleep(5); + + printf("\n####################\nEat Counts\n"); + + for(uint16_t i = 0 ; i < NUM_PHILOSOPHERS ; i++){ + printf("%s: %u\n", philosopher_names[i], philosopher_eat_counts[i]); + } + + printf("####################\n\n"); + + fflush(stdout); + + } + + return 0; +} + diff --git a/OSU Coursework/CS 444 - Operating Systems II/Concurrency Assignments/Concurrency 2/makefile b/OSU Coursework/CS 444 - Operating Systems II/Concurrency Assignments/Concurrency 2/makefile new file mode 100644 index 0000000..e4195c9 --- /dev/null +++ b/OSU Coursework/CS 444 - Operating Systems II/Concurrency Assignments/Concurrency 2/makefile @@ -0,0 +1,8 @@ +all: clean build + +clean: + rm -f *.o + rm -f concurrency2 + +build: + gcc main.c mt19937ar.h -o concurrency2 -std=c99 -lpthread -lrt \ No newline at end of file diff --git a/OSU Coursework/CS 444 - Operating Systems II/Concurrency Assignments/Concurrency 2/mt19937ar.h b/OSU Coursework/CS 444 - Operating Systems II/Concurrency Assignments/Concurrency 2/mt19937ar.h new file mode 100644 index 0000000..0c18485 --- /dev/null +++ b/OSU Coursework/CS 444 - Operating Systems II/Concurrency Assignments/Concurrency 2/mt19937ar.h @@ -0,0 +1,190 @@ +/* + A C-program for MT19937, with initialization improved 2002/1/26. + Coded by Takuji Nishimura and Makoto Matsumoto. + + Before using, initialize the state by using init_genrand(seed) + or init_by_array(init_key, key_length). + + Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. The names of its contributors may not be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + + Any feedback is very welcome. + http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html + email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space) +*/ + +#include + +/* Period parameters */ +#define N 624 +#define M 397 +#define MATRIX_A 0x9908b0dfUL /* constant vector a */ +#define UPPER_MASK 0x80000000UL /* most significant w-r bits */ +#define LOWER_MASK 0x7fffffffUL /* least significant r bits */ + +static unsigned long mt[N]; /* the array for the state vector */ +static int mti=N+1; /* mti==N+1 means mt[N] is not initialized */ + +/* initializes mt[N] with a seed */ +void init_genrand(unsigned long s) +{ + mt[0]= s & 0xffffffffUL; + for (mti=1; mti> 30)) + mti); + /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */ + /* In the previous versions, MSBs of the seed affect */ + /* only MSBs of the array mt[]. */ + /* 2002/01/09 modified by Makoto Matsumoto */ + mt[mti] &= 0xffffffffUL; + /* for >32 bit machines */ + } +} + +/* initialize by an array with array-length */ +/* init_key is the array for initializing keys */ +/* key_length is its length */ +/* slight change for C++, 2004/2/26 */ +void init_by_array(unsigned long init_key[], int key_length) +{ + int i, j, k; + init_genrand(19650218UL); + i=1; j=0; + k = (N>key_length ? N : key_length); + for (; k; k--) { + mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1664525UL)) + + init_key[j] + j; /* non linear */ + mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */ + i++; j++; + if (i>=N) { mt[0] = mt[N-1]; i=1; } + if (j>=key_length) j=0; + } + for (k=N-1; k; k--) { + mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1566083941UL)) + - i; /* non linear */ + mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */ + i++; + if (i>=N) { mt[0] = mt[N-1]; i=1; } + } + + mt[0] = 0x80000000UL; /* MSB is 1; assuring non-zero initial array */ +} + +/* generates a random number on [0,0xffffffff]-interval */ +unsigned long genrand_int32(void) +{ + unsigned long y; + static unsigned long mag01[2]={0x0UL, MATRIX_A}; + /* mag01[x] = x * MATRIX_A for x=0,1 */ + + if (mti >= N) { /* generate N words at one time */ + int kk; + + if (mti == N+1) /* if init_genrand() has not been called, */ + init_genrand(5489UL); /* a default initial seed is used */ + + for (kk=0;kk> 1) ^ mag01[y & 0x1UL]; + } + for (;kk> 1) ^ mag01[y & 0x1UL]; + } + y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK); + mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1UL]; + + mti = 0; + } + + y = mt[mti++]; + + /* Tempering */ + y ^= (y >> 11); + y ^= (y << 7) & 0x9d2c5680UL; + y ^= (y << 15) & 0xefc60000UL; + y ^= (y >> 18); + + return y; +} + +/* generates a random number on [0,0x7fffffff]-interval */ +long genrand_int31(void) +{ + return (long)(genrand_int32()>>1); +} + +/* generates a random number on [0,1]-real-interval */ +double genrand_real1(void) +{ + return genrand_int32()*(1.0/4294967295.0); + /* divided by 2^32-1 */ +} + +/* generates a random number on [0,1)-real-interval */ +double genrand_real2(void) +{ + return genrand_int32()*(1.0/4294967296.0); + /* divided by 2^32 */ +} + +/* generates a random number on (0,1)-real-interval */ +double genrand_real3(void) +{ + return (((double)genrand_int32()) + 0.5)*(1.0/4294967296.0); + /* divided by 2^32 */ +} + +/* generates a random number on [0,1) with 53-bit resolution*/ +double genrand_res53(void) +{ + unsigned long a=genrand_int32()>>5, b=genrand_int32()>>6; + return(a*67108864.0+b)*(1.0/9007199254740992.0); +} +/* These real versions are due to Isaku Wada, 2002/01/09 added */ + +//int main(void) +//{ +// int i; +// unsigned long init[4]={0x123, 0x234, 0x345, 0x456}, length=4; +// init_by_array(init, length); +// printf("1000 outputs of genrand_int32()\n"); +// for (i=0; i<1000; i++) { +// printf("%10lu ", genrand_int32()); +// if (i%5==4) printf("\n"); +// } +// printf("\n1000 outputs of genrand_real2()\n"); +// for (i=0; i<1000; i++) { +// printf("%10.8f ", genrand_real2()); +// if (i%5==4) printf("\n"); +// } +// return 0; +//} diff --git a/OSU Coursework/CS 444 - Operating Systems II/Concurrency Assignments/Concurrency 2/readme.txt b/OSU Coursework/CS 444 - Operating Systems II/Concurrency Assignments/Concurrency 2/readme.txt new file mode 100644 index 0000000..d0c0f5e --- /dev/null +++ b/OSU Coursework/CS 444 - Operating Systems II/Concurrency Assignments/Concurrency 2/readme.txt @@ -0,0 +1,5 @@ +Corwin Perren - Concurrency HW 2 + +To make this program on the os server, cd into this directory and run "make". + +To run the program, type "./concurrency2" into the terminal and hit enter. \ No newline at end of file diff --git a/OSU Coursework/CS 444 - Operating Systems II/Concurrency Assignments/Concurrency 3/makefile b/OSU Coursework/CS 444 - Operating Systems II/Concurrency Assignments/Concurrency 3/makefile new file mode 100644 index 0000000..f8f8e81 --- /dev/null +++ b/OSU Coursework/CS 444 - Operating Systems II/Concurrency Assignments/Concurrency 3/makefile @@ -0,0 +1,9 @@ +all: clean build + +clean: + rm -f *.o + rm -f concurrency3_problem1 concurrency3_problem2 + +build: + gcc problem1.c mt19937ar.h -o concurrency3_problem1 -std=c99 -lpthread -lrt + gcc problem2.c mt19937ar.h -o concurrency3_problem2 -std=c99 -lpthread -lrt diff --git a/OSU Coursework/CS 444 - Operating Systems II/Concurrency Assignments/Concurrency 3/mt19937ar.h b/OSU Coursework/CS 444 - Operating Systems II/Concurrency Assignments/Concurrency 3/mt19937ar.h new file mode 100644 index 0000000..0c18485 --- /dev/null +++ b/OSU Coursework/CS 444 - Operating Systems II/Concurrency Assignments/Concurrency 3/mt19937ar.h @@ -0,0 +1,190 @@ +/* + A C-program for MT19937, with initialization improved 2002/1/26. + Coded by Takuji Nishimura and Makoto Matsumoto. + + Before using, initialize the state by using init_genrand(seed) + or init_by_array(init_key, key_length). + + Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. The names of its contributors may not be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + + Any feedback is very welcome. + http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html + email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space) +*/ + +#include + +/* Period parameters */ +#define N 624 +#define M 397 +#define MATRIX_A 0x9908b0dfUL /* constant vector a */ +#define UPPER_MASK 0x80000000UL /* most significant w-r bits */ +#define LOWER_MASK 0x7fffffffUL /* least significant r bits */ + +static unsigned long mt[N]; /* the array for the state vector */ +static int mti=N+1; /* mti==N+1 means mt[N] is not initialized */ + +/* initializes mt[N] with a seed */ +void init_genrand(unsigned long s) +{ + mt[0]= s & 0xffffffffUL; + for (mti=1; mti> 30)) + mti); + /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */ + /* In the previous versions, MSBs of the seed affect */ + /* only MSBs of the array mt[]. */ + /* 2002/01/09 modified by Makoto Matsumoto */ + mt[mti] &= 0xffffffffUL; + /* for >32 bit machines */ + } +} + +/* initialize by an array with array-length */ +/* init_key is the array for initializing keys */ +/* key_length is its length */ +/* slight change for C++, 2004/2/26 */ +void init_by_array(unsigned long init_key[], int key_length) +{ + int i, j, k; + init_genrand(19650218UL); + i=1; j=0; + k = (N>key_length ? N : key_length); + for (; k; k--) { + mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1664525UL)) + + init_key[j] + j; /* non linear */ + mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */ + i++; j++; + if (i>=N) { mt[0] = mt[N-1]; i=1; } + if (j>=key_length) j=0; + } + for (k=N-1; k; k--) { + mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1566083941UL)) + - i; /* non linear */ + mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */ + i++; + if (i>=N) { mt[0] = mt[N-1]; i=1; } + } + + mt[0] = 0x80000000UL; /* MSB is 1; assuring non-zero initial array */ +} + +/* generates a random number on [0,0xffffffff]-interval */ +unsigned long genrand_int32(void) +{ + unsigned long y; + static unsigned long mag01[2]={0x0UL, MATRIX_A}; + /* mag01[x] = x * MATRIX_A for x=0,1 */ + + if (mti >= N) { /* generate N words at one time */ + int kk; + + if (mti == N+1) /* if init_genrand() has not been called, */ + init_genrand(5489UL); /* a default initial seed is used */ + + for (kk=0;kk> 1) ^ mag01[y & 0x1UL]; + } + for (;kk> 1) ^ mag01[y & 0x1UL]; + } + y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK); + mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1UL]; + + mti = 0; + } + + y = mt[mti++]; + + /* Tempering */ + y ^= (y >> 11); + y ^= (y << 7) & 0x9d2c5680UL; + y ^= (y << 15) & 0xefc60000UL; + y ^= (y >> 18); + + return y; +} + +/* generates a random number on [0,0x7fffffff]-interval */ +long genrand_int31(void) +{ + return (long)(genrand_int32()>>1); +} + +/* generates a random number on [0,1]-real-interval */ +double genrand_real1(void) +{ + return genrand_int32()*(1.0/4294967295.0); + /* divided by 2^32-1 */ +} + +/* generates a random number on [0,1)-real-interval */ +double genrand_real2(void) +{ + return genrand_int32()*(1.0/4294967296.0); + /* divided by 2^32 */ +} + +/* generates a random number on (0,1)-real-interval */ +double genrand_real3(void) +{ + return (((double)genrand_int32()) + 0.5)*(1.0/4294967296.0); + /* divided by 2^32 */ +} + +/* generates a random number on [0,1) with 53-bit resolution*/ +double genrand_res53(void) +{ + unsigned long a=genrand_int32()>>5, b=genrand_int32()>>6; + return(a*67108864.0+b)*(1.0/9007199254740992.0); +} +/* These real versions are due to Isaku Wada, 2002/01/09 added */ + +//int main(void) +//{ +// int i; +// unsigned long init[4]={0x123, 0x234, 0x345, 0x456}, length=4; +// init_by_array(init, length); +// printf("1000 outputs of genrand_int32()\n"); +// for (i=0; i<1000; i++) { +// printf("%10lu ", genrand_int32()); +// if (i%5==4) printf("\n"); +// } +// printf("\n1000 outputs of genrand_real2()\n"); +// for (i=0; i<1000; i++) { +// printf("%10.8f ", genrand_real2()); +// if (i%5==4) printf("\n"); +// } +// return 0; +//} diff --git a/OSU Coursework/CS 444 - Operating Systems II/Concurrency Assignments/Concurrency 3/problem1.c b/OSU Coursework/CS 444 - Operating Systems II/Concurrency Assignments/Concurrency 3/problem1.c new file mode 100644 index 0000000..26f5857 --- /dev/null +++ b/OSU Coursework/CS 444 - Operating Systems II/Concurrency Assignments/Concurrency 3/problem1.c @@ -0,0 +1,172 @@ +/* + * File: main.c + * Author: caperren + * + * Created on April 27th, 2018 + */ + +#include "mt19937ar.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Program defines you might want to change +#define MAX_NUM_THREADS 4 +#define MAX_RESOURCE_USAGE 3 + +#define MIN_RANDOM_USE_WAIT 3 +#define MAX_RANDOM_USE_WAIT 5 + +//RDRAND value to check for +#define RDRAND_FLAG (1 << 30) + +sem_t resource_semaphore; +uint8_t wait_for_resource_recovery = 0; + +// Get random number based on whether rdrand is supported. +uint8_t get_random_number(uint8_t min, uint8_t max) { + uint8_t rand_val; + unsigned long seed; + + unsigned int eax; + unsigned int ebx; + unsigned int ecx; + unsigned int edx; + + eax = 0x01; + + // ASM for checking if RDRAND supported + __asm__ __volatile__("cpuid" + : "=a" (eax), + "=b" (ebx), + "=c" (ecx), + "=d" (edx) + : "a" (1), + "c" (0) + ); + + // Seed random with /dev/random + int random = open("/dev/random", O_RDONLY); + read(random, &seed, sizeof (seed)); + + unsigned int random_value; + + if ((ecx & RDRAND_FLAG) == RDRAND_FLAG) { + char return_code = 0; + char count = 0; + + // ASM for RDRAND + while(return_code != 1 && count < 10){ + __asm__ volatile( + "rdrand %0 ; setc %1" + : "=r" (random_value), "=qm" (return_code) + ); + + count++; + } + } else { + // Twister if RDRAND not supported + init_genrand(seed); + random_value = genrand_int32(); + } + + return (random_value % (max + 1 - min)) + min; +} + + +void resource_user_wait(uint8_t id, uint8_t *wait_kind){ + uint8_t random = get_random_number(MIN_RANDOM_USE_WAIT, MAX_RANDOM_USE_WAIT); + + printf("Resource user %d waiting %u seconds for %s.\n", id, random, wait_kind); + fflush(stdout); + + sleep(random); +} + +void *resource_user(void *thread_num){ + + uint8_t thread_number = *((uint8_t *)thread_num); + + printf("Resourcing using thread with id: %d now running.\n", thread_number); + fflush(stdout); + + while(1){ + resource_user_wait(thread_number, "initial wait"); + + if(wait_for_resource_recovery){ + printf("Resource user %d waiting for recovery of all resources.\n", thread_number); + fflush(stdout); + while(wait_for_resource_recovery); + } + + sem_wait(&resource_semaphore); + + printf("Resource user %d now using resource.\n", thread_number); + fflush(stdout); + + resource_user_wait(thread_number, "usage wait"); + + printf("Resource user %d done with resource.\n", thread_number); + fflush(stdout); + + sem_post(&resource_semaphore); + } +} + +int main(int argc, char **argv) { + // Containers to hold our threads, and the philosopher index + pthread_t usage_threads[MAX_NUM_THREADS]; + uint8_t thread_id_numbers[MAX_NUM_THREADS]; + + // Initialize semaphores, and arrays used to keep track of things + sem_init(&resource_semaphore, 0, MAX_RESOURCE_USAGE); + + for(uint8_t i = 0 ; i < MAX_NUM_THREADS ; i++){ + thread_id_numbers[i] = i; + } + + // Create all the philosopher threads + for(uint8_t i = 0 ; i < MAX_NUM_THREADS ; i++){ + if(pthread_create(&usage_threads[i], NULL, resource_user, &thread_id_numbers[i])) { + fprintf(stderr, "Error creating thread\n"); + return 1; + } + } + + int used_semaphores = 0; + uint8_t resources_left = MAX_RESOURCE_USAGE; + uint8_t last_resources_left_value = resources_left; + + + while(1){ + sem_getvalue(&resource_semaphore, &used_semaphores); + + resources_left = MAX_RESOURCE_USAGE - used_semaphores; + + if(resources_left != last_resources_left_value){ + + printf("Manager ### Resources currently used: %d\n", resources_left); + fflush(stdout); + + if(resources_left == MAX_RESOURCE_USAGE){ + printf("Manager ### Maximum resources used. Locking out.\n"); + fflush(stdout); + wait_for_resource_recovery = 1; + }else if (resources_left == 0){ + wait_for_resource_recovery = 0; + } + + last_resources_left_value = resources_left; + } + } + + return 0; +} + diff --git a/OSU Coursework/CS 444 - Operating Systems II/Concurrency Assignments/Concurrency 3/problem2.c b/OSU Coursework/CS 444 - Operating Systems II/Concurrency Assignments/Concurrency 3/problem2.c new file mode 100644 index 0000000..5a0e5ba --- /dev/null +++ b/OSU Coursework/CS 444 - Operating Systems II/Concurrency Assignments/Concurrency 3/problem2.c @@ -0,0 +1,339 @@ +/* + * File: main.c + * Author: caperren + * + * Created on April 27th, 2018 + */ + +#include "mt19937ar.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +////////// Program defines you might want to change ////////// +#define NUM_INSERTERS 2 +#define NUM_DELETERS 2 +#define NUM_SEARCHERS 2 + +#define MIN_NUMBER 0 +#define MAX_NUMBER 10 + +#define MIN_SLEEP_INSERTER 2 +#define MAX_SLEEP_INSERTER 4 + +#define MIN_SLEEP_SEARCHER 1 +#define MAX_SLEEP_SEARCHER 2 + +#define MIN_SLEEP_DELETER 10 +#define MAX_SLEEP_DELETER 15 + +////////// Global variables and structs for linked list ////////// +typedef struct linked_list { + struct linked_list *next; + uint16_t value; +} linked_list; + +linked_list *list_head = NULL; +uint16_t list_size = 0; + + +////////// Global variables and structs for threading and sempaphores ////////// +typedef struct light_switch { + uint16_t counter; + sem_t mutex; +} light_switch; + + +sem_t no_searches_semaphore; +sem_t no_insertions_semaphore; +sem_t insertion_mutex; + +light_switch insertion_light_switch; +light_switch search_light_switch; + + +////////// Other global variables ////////// +//RDRAND value to check for +#define RDRAND_FLAG (1 << 30) + +// Get random number based on whether rdrand is supported. +uint8_t get_random_number(uint8_t min, uint8_t max) { + uint8_t rand_val; + unsigned long seed; + + unsigned int eax; + unsigned int ebx; + unsigned int ecx; + unsigned int edx; + + eax = 0x01; + + // ASM for checking if RDRAND supported + __asm__ __volatile__("cpuid" + : "=a" (eax), + "=b" (ebx), + "=c" (ecx), + "=d" (edx) + : "a" (1), + "c" (0) + ); + + // Seed random with /dev/random + int random = open("/dev/random", O_RDONLY); + read(random, &seed, sizeof (seed)); + + unsigned int random_value; + + if ((ecx & RDRAND_FLAG) == RDRAND_FLAG) { + char return_code = 0; + char count = 0; + + // ASM for RDRAND + while(return_code != 1 && count < 10){ + __asm__ volatile( + "rdrand %0 ; setc %1" + : "=r" (random_value), "=qm" (return_code) + ); + + count++; + } + } else { + // Twister if RDRAND not supported + init_genrand(seed); + random_value = genrand_int32(); + } + + return (random_value % (max + 1 - min)) + min; +} + +void insert_linked_list(uint16_t value){ + linked_list *new = malloc(sizeof(linked_list)); + new->next = NULL; + new->value = value; + + if(list_head == NULL){ + list_head = new; + }else{ + linked_list *cursor = list_head; + + while(cursor->next != NULL){ + cursor = cursor->next; + } + cursor->next = new; + } + + list_size++; +} + +void delete_position_from_linked_list(uint16_t position) { + linked_list *cursor_prev = list_head; + linked_list *cursor_current = list_head; + + if(list_head == NULL || position >= list_size){ + return; + } + + if(position == 0){ + list_head = cursor_current->next; + free(cursor_current); + }else{ + for(uint16_t i = 0 ; i < position ; i++){ + cursor_prev = cursor_current; + cursor_current = cursor_current->next; + } + + cursor_prev->next = cursor_current->next; + free(cursor_current); + } + + list_size--; +} + +int16_t position_of_value_linked_list(uint16_t value){ + linked_list *cursor_current = list_head; + + if(list_head == NULL){ + return -1; + } + + uint16_t count = 0; + + do{ + if(cursor_current->value == value){ + return count; + } + + count++; + cursor_current = cursor_current->next; + }while(cursor_current != NULL); + + return -1; +} + +void light_switch_lock(light_switch *current_light_switch, sem_t *current_semaphore){ + sem_wait(¤t_light_switch->mutex); + current_light_switch->counter++; + + if(current_light_switch->counter == 1){ + sem_wait(current_semaphore); + } + + sem_post(¤t_light_switch->mutex); +} + +void light_switch_unlock(light_switch *current_light_switch, sem_t *current_semaphore){ + sem_wait(¤t_light_switch->mutex); + current_light_switch->counter--; + + if(current_light_switch->counter == 0){ + sem_post(current_semaphore); + } + + sem_post(¤t_light_switch->mutex); +} + +void *inserter_thread(){ + printf("Inserter starting.\n"); + fflush(stdout); + + sleep(2); //Do this so you can easily see threads starting + + while(1){ + uint16_t new_number = get_random_number(MIN_NUMBER, MAX_NUMBER); + uint16_t sleep_time = get_random_number(MIN_SLEEP_INSERTER, MAX_SLEEP_INSERTER); + + printf("Inserter going to sleep for %d seconds.\n", sleep_time); + fflush(stdout); + sleep(sleep_time); + + printf("Inserter awake and waiting for access.\n"); + fflush(stdout); + light_switch_lock(&insertion_light_switch, &no_insertions_semaphore); + sem_wait(&insertion_mutex); + + printf("Inserter now has access.\n"); + printf("Inserting number %u.\n", new_number); + fflush(stdout); + insert_linked_list(new_number); + + sem_post(&insertion_mutex); + light_switch_unlock(&insertion_light_switch, &no_insertions_semaphore); + } +} + +void *searcher_thread(){ + printf("Searcher starting.\n"); + fflush(stdout); + + sleep(2); //Do this so you can easily see threads starting + + while(1){ + uint16_t search_value = get_random_number(MIN_NUMBER, MAX_NUMBER); + uint16_t sleep_time = get_random_number(MIN_SLEEP_SEARCHER, MAX_SLEEP_SEARCHER); + + printf("Searcher going to sleep for %d seconds.\n", sleep_time); + fflush(stdout); + sleep(sleep_time); + + printf("Searcher awake and waiting for access.\n"); + fflush(stdout); + light_switch_lock(&search_light_switch, &no_searches_semaphore); + + printf("Searcher has access.\n"); + fflush(stdout); + + int16_t value = position_of_value_linked_list(search_value); + + if(value != -1){ + printf("Search successful. Found value %d.\n", value); + } else { + printf("Search unsuccessful. Could not find value %u.\n", search_value); + } + fflush(stdout); + + light_switch_unlock(&search_light_switch, &no_searches_semaphore); + + } +} + +void *deleter_thread(){ + printf("Deleter starting.\n"); + fflush(stdout); + + sleep(2); //Do this so you can easily see threads starting + + while(1){ + uint16_t sleep_time = get_random_number(MIN_SLEEP_DELETER, MAX_SLEEP_DELETER); + + printf("Deleter going to sleep for %d seconds.\n", sleep_time); + fflush(stdout); + sleep(sleep_time); + + printf("Deleter awake and waiting for access.\n"); + fflush(stdout); + sem_wait(&no_searches_semaphore); + sem_wait(&no_insertions_semaphore); + + uint16_t delete_position = get_random_number(0, list_size); + + printf("Deleter has access.\n"); + printf("Deleting node at position %d.\n", delete_position); + fflush(stdout); + delete_position_from_linked_list(delete_position); + + sem_post(&no_insertions_semaphore); + sem_post(&no_searches_semaphore); + } +} + +int main(int argc, char **argv) { + // Storage for threads + pthread_t inserters[NUM_INSERTERS]; + pthread_t searchers[NUM_INSERTERS]; + pthread_t deleters[NUM_INSERTERS]; + + // Initialize light switches + sem_init(&insertion_light_switch.mutex, 1, 1); + insertion_light_switch.counter = 0; + + sem_init(&search_light_switch.mutex, 1, 1); + search_light_switch.counter = 0; + + // Initialize other semaphores and mutex + sem_init(&no_insertions_semaphore, 1, 1); + sem_init(&no_searches_semaphore, 1, 1); + sem_init(&insertion_mutex, 1, 1); + + // Spin up threads + for(uint8_t i = 0 ; i < NUM_INSERTERS ; i++){ + pthread_create(&inserters[i], NULL, inserter_thread, NULL); + } + + for(uint8_t i = 0 ; i < NUM_SEARCHERS ; i++){ + pthread_create(&searchers[i], NULL, searcher_thread, NULL); + } + + for(uint8_t i = 0 ; i < NUM_DELETERS ; i++){ + pthread_create(&deleters[i], NULL, deleter_thread, NULL); + } + + // Wait for threads to join for completion. + for(uint8_t i = 0 ; i < NUM_INSERTERS ; i++){ + pthread_join(inserters[i], NULL); + } + + for(uint8_t i = 0 ; i < NUM_SEARCHERS ; i++){ + pthread_join(searchers[i], NULL); + } + + for(uint8_t i = 0 ; i < NUM_DELETERS ; i++){ + pthread_join(deleters[i], NULL); + } +} diff --git a/OSU Coursework/CS 444 - Operating Systems II/Concurrency Assignments/Concurrency 3/readme.txt b/OSU Coursework/CS 444 - Operating Systems II/Concurrency Assignments/Concurrency 3/readme.txt new file mode 100644 index 0000000..ed3b332 --- /dev/null +++ b/OSU Coursework/CS 444 - Operating Systems II/Concurrency Assignments/Concurrency 3/readme.txt @@ -0,0 +1,6 @@ +Corwin Perren - Concurrency HW 3 + +To make this program on the os server, cd into this directory and run "make". + +To run program1, type "./concurrency3_problem1" into the terminal and hit enter. +To run program2, type "./concurrency3_problem2" into the terminal and hit enter. \ No newline at end of file diff --git a/OSU Coursework/CS 444 - Operating Systems II/Concurrency Assignments/Concurrency 4/main.c b/OSU Coursework/CS 444 - Operating Systems II/Concurrency Assignments/Concurrency 4/main.c new file mode 100644 index 0000000..9eda0ed --- /dev/null +++ b/OSU Coursework/CS 444 - Operating Systems II/Concurrency Assignments/Concurrency 4/main.c @@ -0,0 +1,262 @@ +/* + * File: main.c + * Author: caperren + * + * Created on June 1st, 2018 + */ +#define _POSIX_C_SOURCE 199309L + +#include "mt19937ar.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Program defines you might want to change +#define NUM_BARBERSHOP_WAITING_ROOM_CHAIRS 5 + +// Program defines that don't get changed +#define NUM_CUSTOMER_THREADS (NUM_BARBERSHOP_WAITING_ROOM_CHAIRS * 2) + +#define MIN_RANDOM_WAIT_CUSTOMER_RESPAWN 4 +#define MAX_RANDOM_WAIT_CUSTOMER_RESPAWN 8 + +#define MIN_RANDOM_HAIRCUT_TIME 2 +#define MAX_RANDOM_HAIRCUT_TIME 4 + +//RDRAND value to check for +#define RDRAND_FLAG (1 << 30) + +// Global Variables +sem_t waiting_room_chairs_semaphore; +sem_t ticket_dispenser_semaphore; +sem_t barber_chair_semaphore; + +uint16_t current_ticket_number = 1; +uint16_t barber_servicing_ticket = 0; + +uint8_t haircut_started = 0; +uint8_t haircut_over = 0; + +struct timespec thread_sleep_time; + +/////////////////////////////////////////////////////////////////// +// Get random number based on whether rdrand is supported. +uint8_t get_random_number(uint8_t min, uint8_t max) { + uint8_t rand_val; + unsigned long seed; + + unsigned int eax; + unsigned int ebx; + unsigned int ecx; + unsigned int edx; + + eax = 0x01; + + // ASM for checking if RDRAND supported + __asm__ __volatile__("cpuid" + : "=a" (eax), + "=b" (ebx), + "=c" (ecx), + "=d" (edx) + : "a" (1), + "c" (0) + ); + + // Seed random with /dev/random + int random = open("/dev/random", O_RDONLY); + read(random, &seed, sizeof (seed)); + + unsigned int random_value; + + if ((ecx & RDRAND_FLAG) == RDRAND_FLAG) { + char return_code = 0; + char count = 0; + + // ASM for RDRAND + while(return_code != 1 && count < 10){ + __asm__ volatile( + "rdrand %0 ; setc %1" + : "=r" (random_value), "=qm" (return_code) + ); + + count++; + } + } else { + // Twister if RDRAND not supported + init_genrand(seed); + random_value = genrand_int32(); + } + + return (random_value % (max + 1 - min)) + min; +} + +void get_hair_cut(uint16_t customer_thread_id, uint16_t ticket_id){ + + while(!haircut_started){ + nanosleep(&thread_sleep_time, NULL); + } + + printf("Customer heading to barbers chair with ticket number %u.\n", ticket_id); + fflush(stdout); + + sem_wait(&barber_chair_semaphore); + + printf("Customer with thread id %u and ticket number %u sat down and getting haircut.\n", customer_thread_id, ticket_id); + fflush(stdout); + + while(!haircut_over){ + nanosleep(&thread_sleep_time, NULL); + } + + sem_post(&barber_chair_semaphore); + +} + +void cut_hair(){ + uint16_t sleep_time = get_random_number(MIN_RANDOM_HAIRCUT_TIME, MAX_RANDOM_HAIRCUT_TIME); + int customer_in_chair = 1; + + haircut_over = 0; + haircut_started = 1; + + printf("Barber waiting for customer to sit down with ticket number %d.\n", barber_servicing_ticket); + fflush(stdout); + while(customer_in_chair > 0){ + sem_getvalue(&barber_chair_semaphore, &customer_in_chair); + nanosleep(&thread_sleep_time, NULL); + + } + + printf("Barber giving haircut to ticket number %d for %d seconds.\n", barber_servicing_ticket, sleep_time); + fflush(stdout); + + sleep(sleep_time); + + haircut_started = 0; + haircut_over = 1; + + while(customer_in_chair <= 0){ + sem_getvalue(&barber_chair_semaphore, &customer_in_chair); + nanosleep(&thread_sleep_time, NULL); + } + + printf("Barber finished haircut for ticket number %d.\n", barber_servicing_ticket); + fflush(stdout); +} + +// If waiting room is empty, sleep until woken up by customer +// If customer, cut_hair +void *barber(){ + printf("Barber thread started.\n"); + fflush(stdout); + + int used_waiting_room_chairs = 0; + + while(1){ + // Check if anyone is in the waiting room + sem_getvalue(&waiting_room_chairs_semaphore, &used_waiting_room_chairs); + + if(used_waiting_room_chairs == 5){ + nanosleep(&thread_sleep_time, NULL); + continue; + } + + // Tell customers next ticket number + barber_servicing_ticket++; + + // Service the customer + cut_hair(); + } +} + +// If the waiting room is full, customer leaves +// If waiting room has empty chair, sits in chair, unless barber is ready +// When ready, sits in chair and runs get_hair_cut, then leaves +void *customer(void *thread_id_number){ + uint16_t thread_id = *((uint16_t *)thread_id_number); + + printf("Customer thread with id %d started.\n", thread_id); + fflush(stdout); + + int used_waiting_room_chairs = 0; + uint16_t customer_ticket_number = 0; + + while(1){ + // Wait before deciding to enter store + uint16_t sleep_time = get_random_number(MIN_RANDOM_WAIT_CUSTOMER_RESPAWN, MAX_RANDOM_WAIT_CUSTOMER_RESPAWN); + sleep(sleep_time); + + // Check if seats are full, exit store if full + sem_getvalue(&waiting_room_chairs_semaphore, &used_waiting_room_chairs); + + if(used_waiting_room_chairs == 0){ + printf("Customer thread with id %d entered store, but was full. Leaving.\n", thread_id); + fflush(stdout); + continue; + } + + // There's space in the waiting room, take a seat and a number + sem_wait(&waiting_room_chairs_semaphore); + sem_wait(&ticket_dispenser_semaphore); + customer_ticket_number = current_ticket_number; + current_ticket_number++; + sem_post(&ticket_dispenser_semaphore); + + printf("Customer thread with id %d has ticket number %u.\n", thread_id, current_ticket_number); + fflush(stdout); + + // Wait until our number is called + while(barber_servicing_ticket != customer_ticket_number){ + nanosleep(&thread_sleep_time, NULL); + } + + // It's time for a haircut, give up our seat in the waiting room + sem_post(&waiting_room_chairs_semaphore); + + // Get a haircut + get_hair_cut(thread_id, customer_ticket_number); + } +} + +int main(int argc, char **argv) { + // Setup thread sleep variable + thread_sleep_time.tv_nsec = 10000000; + thread_sleep_time.tv_sec = 0; + + // Storage for threads + pthread_t barber_thread; + pthread_t potential_customers_threads[NUM_CUSTOMER_THREADS]; + uint16_t customers_thread_ids[NUM_CUSTOMER_THREADS]; + + + // Initialize semaphores + sem_init(&waiting_room_chairs_semaphore, 1, NUM_BARBERSHOP_WAITING_ROOM_CHAIRS); + sem_init(&ticket_dispenser_semaphore, 1, 1); + sem_init(&barber_chair_semaphore, 1, 1); + + // Start barber thread + pthread_create(&barber_thread, NULL, barber, NULL); + + // Start potential custom threads + for(uint16_t i = 0 ; i < NUM_CUSTOMER_THREADS ; i++){ + customers_thread_ids[i] = i; + pthread_create(&potential_customers_threads[i], NULL, customer, &customers_thread_ids[i]); + } + + // Wait for barber thread to finish + pthread_join(barber_thread, NULL); + + // Wait for customer threads to finish + for(uint8_t i = 0 ; i < NUM_CUSTOMER_THREADS ; i++){ + pthread_join(potential_customers_threads[i], NULL); + } +} + diff --git a/OSU Coursework/CS 444 - Operating Systems II/Concurrency Assignments/Concurrency 4/makefile b/OSU Coursework/CS 444 - Operating Systems II/Concurrency Assignments/Concurrency 4/makefile new file mode 100644 index 0000000..ff08089 --- /dev/null +++ b/OSU Coursework/CS 444 - Operating Systems II/Concurrency Assignments/Concurrency 4/makefile @@ -0,0 +1,8 @@ +all: clean build + +clean: + rm -f *.o + rm -f concurrency4 + +build: + gcc main.c mt19937ar.h -o concurrency4 -std=c99 -lpthread -lrt diff --git a/OSU Coursework/CS 444 - Operating Systems II/Concurrency Assignments/Concurrency 4/mt19937ar.h b/OSU Coursework/CS 444 - Operating Systems II/Concurrency Assignments/Concurrency 4/mt19937ar.h new file mode 100644 index 0000000..0c18485 --- /dev/null +++ b/OSU Coursework/CS 444 - Operating Systems II/Concurrency Assignments/Concurrency 4/mt19937ar.h @@ -0,0 +1,190 @@ +/* + A C-program for MT19937, with initialization improved 2002/1/26. + Coded by Takuji Nishimura and Makoto Matsumoto. + + Before using, initialize the state by using init_genrand(seed) + or init_by_array(init_key, key_length). + + Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. The names of its contributors may not be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + + Any feedback is very welcome. + http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html + email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space) +*/ + +#include + +/* Period parameters */ +#define N 624 +#define M 397 +#define MATRIX_A 0x9908b0dfUL /* constant vector a */ +#define UPPER_MASK 0x80000000UL /* most significant w-r bits */ +#define LOWER_MASK 0x7fffffffUL /* least significant r bits */ + +static unsigned long mt[N]; /* the array for the state vector */ +static int mti=N+1; /* mti==N+1 means mt[N] is not initialized */ + +/* initializes mt[N] with a seed */ +void init_genrand(unsigned long s) +{ + mt[0]= s & 0xffffffffUL; + for (mti=1; mti> 30)) + mti); + /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */ + /* In the previous versions, MSBs of the seed affect */ + /* only MSBs of the array mt[]. */ + /* 2002/01/09 modified by Makoto Matsumoto */ + mt[mti] &= 0xffffffffUL; + /* for >32 bit machines */ + } +} + +/* initialize by an array with array-length */ +/* init_key is the array for initializing keys */ +/* key_length is its length */ +/* slight change for C++, 2004/2/26 */ +void init_by_array(unsigned long init_key[], int key_length) +{ + int i, j, k; + init_genrand(19650218UL); + i=1; j=0; + k = (N>key_length ? N : key_length); + for (; k; k--) { + mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1664525UL)) + + init_key[j] + j; /* non linear */ + mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */ + i++; j++; + if (i>=N) { mt[0] = mt[N-1]; i=1; } + if (j>=key_length) j=0; + } + for (k=N-1; k; k--) { + mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1566083941UL)) + - i; /* non linear */ + mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */ + i++; + if (i>=N) { mt[0] = mt[N-1]; i=1; } + } + + mt[0] = 0x80000000UL; /* MSB is 1; assuring non-zero initial array */ +} + +/* generates a random number on [0,0xffffffff]-interval */ +unsigned long genrand_int32(void) +{ + unsigned long y; + static unsigned long mag01[2]={0x0UL, MATRIX_A}; + /* mag01[x] = x * MATRIX_A for x=0,1 */ + + if (mti >= N) { /* generate N words at one time */ + int kk; + + if (mti == N+1) /* if init_genrand() has not been called, */ + init_genrand(5489UL); /* a default initial seed is used */ + + for (kk=0;kk> 1) ^ mag01[y & 0x1UL]; + } + for (;kk> 1) ^ mag01[y & 0x1UL]; + } + y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK); + mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1UL]; + + mti = 0; + } + + y = mt[mti++]; + + /* Tempering */ + y ^= (y >> 11); + y ^= (y << 7) & 0x9d2c5680UL; + y ^= (y << 15) & 0xefc60000UL; + y ^= (y >> 18); + + return y; +} + +/* generates a random number on [0,0x7fffffff]-interval */ +long genrand_int31(void) +{ + return (long)(genrand_int32()>>1); +} + +/* generates a random number on [0,1]-real-interval */ +double genrand_real1(void) +{ + return genrand_int32()*(1.0/4294967295.0); + /* divided by 2^32-1 */ +} + +/* generates a random number on [0,1)-real-interval */ +double genrand_real2(void) +{ + return genrand_int32()*(1.0/4294967296.0); + /* divided by 2^32 */ +} + +/* generates a random number on (0,1)-real-interval */ +double genrand_real3(void) +{ + return (((double)genrand_int32()) + 0.5)*(1.0/4294967296.0); + /* divided by 2^32 */ +} + +/* generates a random number on [0,1) with 53-bit resolution*/ +double genrand_res53(void) +{ + unsigned long a=genrand_int32()>>5, b=genrand_int32()>>6; + return(a*67108864.0+b)*(1.0/9007199254740992.0); +} +/* These real versions are due to Isaku Wada, 2002/01/09 added */ + +//int main(void) +//{ +// int i; +// unsigned long init[4]={0x123, 0x234, 0x345, 0x456}, length=4; +// init_by_array(init, length); +// printf("1000 outputs of genrand_int32()\n"); +// for (i=0; i<1000; i++) { +// printf("%10lu ", genrand_int32()); +// if (i%5==4) printf("\n"); +// } +// printf("\n1000 outputs of genrand_real2()\n"); +// for (i=0; i<1000; i++) { +// printf("%10.8f ", genrand_real2()); +// if (i%5==4) printf("\n"); +// } +// return 0; +//} diff --git a/OSU Coursework/CS 444 - Operating Systems II/Concurrency Assignments/Concurrency 4/readme.txt b/OSU Coursework/CS 444 - Operating Systems II/Concurrency Assignments/Concurrency 4/readme.txt new file mode 100644 index 0000000..9d61351 --- /dev/null +++ b/OSU Coursework/CS 444 - Operating Systems II/Concurrency Assignments/Concurrency 4/readme.txt @@ -0,0 +1,11 @@ +Corwin Perren - Concurrency HW 4 + +To make this program on the os server, cd into this directory and run "make". + +To run, type "./concurrency4" into the terminal. + +To change the number of chairs in the shop, edit the line in main.c, seen below, +to have the number of desired waiting room chairs. + +#define NUM_BARBERSHOP_WAITING_ROOM_CHAIRS 5 + diff --git a/OSU Coursework/CS 444 - Operating Systems II/Kernel Assignments/Project 1/CS444_project1_4.pdf b/OSU Coursework/CS 444 - Operating Systems II/Kernel Assignments/Project 1/CS444_project1_4.pdf new file mode 100644 index 0000000000000000000000000000000000000000..5fb1f3aa3406ee3057e481b1eb3c0c9845d322d1 GIT binary patch literal 83371 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%0DoggEm!MS{)BJG9={lJhk_X^h**< zChJAfuQ*=Y;rLD}HI0#p1&g`C?EEI5aL}+i90{rwH{ax#WD+ePLf;+Fjf?pY@*Q1P z-&z4QgYzs++G575nBv<-f?S?0^}DZyO%cYBtjt)@;W7i>H>S=^Etz{1|C;XY#L9ES z-5UMQ`)$-5=P3#l3m?WS@tZ(H}Qnz2>wdV ze0Vw4ygdio&4+5xwNi?#w&Nquph{+?8!Yz@X|yOQ91_RgNrS1fQGO@XekaKJJT+0M zjEdxy^%G|&imZh!vCQ~aI2JmovBTGv%LowcRzANJC+$!nrVhqWMPMX;FPiqZMvjfa?E1$S)W^otPo*9t zxu85R0XPJzEK#%j;GxH@J@-#rXNxjG5J1nF^cZ}m;0oh4etA`PP$9uA+%QcM82)k1 z&ab6v73a3x$3f9~5_&L01ZA#FqLx9tMlhjGNf=^hYcNq(eWF%sH@|J`p z-#k!8%)S1))eHM2i9p-Ga!ktRPUOMT@p@MO;CU!go{qDYb{d%Ua*g){UjatI@2W`B z<7*U&wPKbv8lmo_D=Oia_!5CJA%Q*?*vQUN+WMxjN|B_S|>s!8dmTDIsugEk4Ad_htAD?pdspQeEE4fjBits z_Ixy%4Gbph^p~W;ySV`q(Pf^8%lI<3mblemEcq4?T>zxZyQWfOf35b;a+XGX;5`y| zk0iF7xGLxQ^~!hEskCMOx&&xUNpDAShS;(tT14FXy+t{QtbMz?QLyHvN766_VsUsR zq+fT<6u33M&(qRlKE>}vh0HzQ!Mtu%#(>e*Lz6}Af_w{_sYseJIX*OC4d~p<^^2&2 zX(r9p523cd$h-c?p3U=7QPW3y4{FR|@{`n_IU6J=r@Ie!p>1PS6Bzh>KRg{2C8zc6 zOBO>1&b0RtZq|>8iP#e}Y@AFX=)fun<~MX~l-2mJM)2kUR4`7Xj`UxVyaTm>a}~Lx z*PdvvA>(LzY$Zw^TCXC6EfjIi>^@0Euup!8%}|GY7^0h&{Ea#%HP3H#WkI|0z82dh zzh#%hj(habxs;lWl}gkfM2UmM=TO;~hO=qB%=u~ub*~0XxMtC?MNjT};|9B7&z8TI z6_HAaTl&x;xd12Lp@IVNRC0YhjP(wGr|2^YCyLRT_kP&%k+$@|@+gXARnmGxEu!N( zhY(3ICf5v%0qKo`YOjvv@Klzv5AkNygD{*qoZu_Q1wU z+Itoha@65@q-&VfU+Gr{f44`Y>^wn6osDeMmNl$OtE6*GO>QzyeT6cx=n>I5S+-UW zJK#a*5Y(#Mbk!tL1s8v|t7TJ~$o{Tj;0sAhf+UcNDLb^nmqzo6jnxWBm7$-q^p7dwJ$6u6W3I} zfiBQOU5HnHw~!%dRC13ui{}sW|WIG>bznUkRRQ z|4;rtB77j+8Kbp?>05tz@_ZE|E}D5(9DeEg;<(NzX}xWds=;!lv%*&cyxk~=2-M9Zz(gyj#Zd-0rU6qQ$c$L#BwelwSoYTSSd2%<Q@S979H@>|4N0zJAxQ82#TnqzhzR9jRa-kILcP z5g|Q?cUJg;CvDkZs}*u?v1_5OutZfM4aDR%cRPgdPvqP_##;FRV7e@;*u%7&&Yj* zP7!Y2_9`P>$a_P~T6Y&IOk+v(39%E8>;6p++%xjNtzVDS%x4?NXnkMiDTAc3L9=%8 zRa-4+;y|T}dP?O?q1oymsX%q#jfUS}L&5CQ;)TN&!|rrrNS_(ZwcgbqcCu|TSGfPaet+G*(QzU=Aebpet*lWwb zEM-Z;8I&;}%o=j25JHw$nY2@|-*)X16u8)xX7Ee-3#X?{=I%rKC3dF@>o0c@T!*ak zeRsPx{A|AXWaT(nWua$YKyGRJC1okocwuZ);T26IRVg)O7nQ=WzE`vsNJy3g_9`jZ z8R~@TvDMk3Pi9o_6+4SAY*O~gVtVxNcEV{; zX5!J^sJS3KLjg0_;Z}(3o>@{@o30-ge-6#MSKZ9c1TeQfin6&x<;~z~zH-5F8k&nl z-JE8sS{rE!9*Q2gGKF#{pH0Nwu27(!H4K{LF1hRgOK(B4uY*V?q@Wo8H&X=66#{KK z(tXDP8tuFJg%HZdp|>}v2K(^Pkg~IECLBFXE=%)BQkLPKu6;}RbPg^%o7#bzQU;8j z-t<1(f7})sB$6^EO4%pJ3bo&hrkJ&wY`@7R!^i%jSz+l=6VgCjhLo-7zdi2#b$vL& zXgC6yIzCf~=0R2_N#ka}Z=fKz(kdjE#GCr)YSSTTbCf+&t1NcH{{@+~Rd#TyoLWLX z&w*LWvfLVLi+9kbzmkd#hL|(SJ9GE2tr!j7gel%D#+F+k3Yko~8ILMX3HW*7{Tq@R&R0u`G^BYfgZI!ct*+&peqvyjoZmB=N3&sWM{z9J-hSdJ z0iJUWc*-)%bNwUa@y>N01WJO)5dS+OKXb6N>zE6QJPU*Bm;kjA*wVZ>Bs* z$=dUSiPtb$*k#nS%LP9E(c?LkA7E{lK58z?;RT3!4;u$X8NrUCMYi=+U=ua+d#P(Z zmS8`tF)wd8F*$yEMqCw&3@v-PL=;5RrWmi(&IKY+)8@N(2W~3S96`yPWVWPfC%{$< z;2DAkVMKS0V3=^eTpJxiErYx2#+etV8I3p-oyLhRW$Kl$Kj8jc0n;UkkAX#;w3U;?f z88eu|d|rc>g-CzcqL*1%Upw<33MnhMsTO||a)K!)`dX#gN-fh`a(G4B8Q|Fbp>i|B z2=bWPYf6`#I0P%fW<;L{k>EQAs|%5CO>wrz^3@<}y&rv8J^GUo;U7U3wd64sxz2#o zS|{0es?zKy{^7%mH~e~S^bfM-FMOSSyP!!#**llMG=eLXf?i5-wL7vc9vwx;wjpK2 zp0&JZeM01gs>tN5@~#7=RVfnRbfH$<%^*AJ%FWlQHL4^f%4vRbX0=u^WS{e?a=pK2 z7%hKY#?kX><5-w*v$7rpSVk(Z){iprZ_gz|9s>&KI1LAs4on77bEA1Sk+uSf zbof@So!!Msuq~%a2nh1Ai*?A9AvLVgYG-6wj(r+Ux>Az4LQU|59+{(>$Fn`V6ppRdB_O55@)KWe{G?B79LlnhL z-=3koFNQqB{(c?SQVbzEBD0`m^X*o%=Jo6!6dNlXwul)NkgQC8n@4{TTw}Om%I@GG z0~9GP9XHx*WR1=(d0V!b6+b_j)$y(ZFA{BVOjBadnBhZ?L2q;gSTr5b4ZR1mL(L+7 zy<=zNHLXBhgL@pvHd|WBAM?#o_~f|UN)S-tbu{|I6^ryhhA2dfp^Ml$>kSEOU6uJK zimbtI9u)>v%!wFYAy*zI&+~B~F1kub zKe3jTPZZp9s8+7WJQ(Uh#?G-{cZINPMwPI01A~&dSv%oA?SD)hzn{=3?>c_7Fm!XF!fgEEn+Tr9r1uMeK0%U8qIf{jWj59hi=Vq|=R7H?-*cdi{!nQ)p14Y##&qKvok9Mq0n$uGekZu?r? zQR<~HIQL)uj9sRPHjWaHgBVl=4O)-OBTVMJ)o~zKFTH|%j8xT5J*oNF8Y;jYu`N0t zwv34`BT$1{y!*(@Rwsst<9CbBOqSibb#yBrYEq*I>Lngo7Fr75`dhtnKh$Bc*e*It z+eZ{+5B2B7QKtNtnC~Xyo30V2l8nB#xO2OYI@MhF!+}8VSCqXPX+-Db2yG=6$00Ku zYA=C=-`e{AEXa3+fz+`$-MD1mmM*3y2(^GA9_ig~CR1Yl-9-~QPvzx8NPw#z$+y}2 z??Oxg1P(EMC>xmG31n5Yi!1%t^TT042-Bj$~vbe+a?nfR7>12 z*m4es+{VCK{<=xt3kp19&H|oK){DJIn~!-sKJv}@i~Q?*<~a+vQg)`&IWy*C*C3>z z?vqN87I4iKf{jGh1@F5(-OEimOKs`ix&hB@i7(r&To&ACP{}BaU@Ax~%!l;F8*xHB z6q|F%+(qyl8Z9!`ieR<~?(%KuDlQbIe7yT*sbVfe&4wACCiUu#l!_08Vks-~H?CP9 zReeD5Lkrf>Rr#h|6=jBJBuD&b$miW#7eyO$)qC~7BW?jIz4qT0y@GK{36r&vW}Me8 zO&TgSKB_WR3i?rWIMPVNaI7O`DuoECt99K(Y0P%QPn}eWuBQt;VBRQ=kNHhk6mXX+ z?tfR-E#TMFE5Y&0HFzsf|6WrMt}aBJ3WLfOtfyjnyl%a6D|0S$w&-VQd3!!4H~TX6 zhiRh(ICLDTCk-_HT|r>O$wXXDwgZeu@7N0Lu^i3r&+DTT3%5Vwra{vWeGl`||oXfH=Lo}e8k8k7{jY>>(v5vqgZ z$q&xA8bdOxe2Mz;6XB({HXn;1w*2!`;8@vSiao{Q@l{HLQhg_ChL_*r^G=6q`*O~g z_x5o6lrSp1g2|UTMMby4do&!I&VuqxDU^&|a)wv&*eOYx8@1r^ z0;btC2Maj(7_YK9&uD$=xgDm%`{+QgR7vJd9^5`V53R%ax>}xk_p^-Z7@r1!uxe<) zhfS>q=`BrEr7d*cY{MX*M+Ya1Hc9l%K4bAfT+(c|(3mllTQ0ReNyul)lfZRz@3hUI zd(-plr?i4abQxu48Wo~g9}_mv6dI8H{jyJ)T#qIkl3Y6?zVgP(y>Uiho;75p{}uaK&_ zepzU6#*YyQ^eEA5F{%<%3%Lvrd~di(xzqn+c}{H!03qcf?bvCFP_;Aevy{p^3yIEI2UC%-w437TbA zK}#uU>_i%-!r=HI{j;nSYMMlt@&pAgByi7c>k-fUr4fTChBq=!GM*fEU;JVD#S=$} z7|*5OcQ2iub_+Io0DCh{_0|y)QMktyg+eTwbH(n}AJ(0FYFFH<-Xu2ImKqqDc#;Dv0r!nKq81$9GdI{;=^ zTL`A|q?VE#$4J#2-tZAvvHMHIZa9=e4cdbkX0#m2921S4*nppOmEdeb{LF6sDg@4? zJhQR^WJD3!8J5Le)2**DFpV?r(I_fhM`c1CbwloYKKqa+qj>n558B)GyJIzIO%o!P z19a0A@pj}XK7Qpi$I-44INY{R)^?Ry+L!~0#?PlgPpV05kx!-R#d?kw1Buwmil*8P zMtW|mhcmB4@N!=GtnKv0OG?1!4JW=_>92s@90!x;*dsfr`&iqkv8Db70Qu{+L06r6 z>Pk_4w~x>~NoP$b*E=Q=$G-^25}WM5RpfWpPF;)(%DRTE!Jw<0EfS=rZ*>}f3Aua03AX!NtGX_e7XJ;PX|86Q>JSR$qEKd z418XtSm#S(@pP|oD?GBFV4#2m1Z1+)OD(g^o7I$B!stjpmYB!mM_YnW1N(n(fpYC8 z3h3bQvM`^%Ljw0G3l>uZHsTH}KE8h)?uRMay4?Eq$TpW42qw-)=uX7!tVq$W&j#wF zAr%Tky!uLcE=S<$hw>M28#0MOXs1BnczdGj>`=7+m80T|0)rjT-aT{n=kiD|=c(xs z-O%vckplkxe&=lZ{?{mg5d%n=(y~My&I`{!jJ*ROCtRkm z1O-_*ul6#YWb?lGXZ)XR`34%-QSdJwTpw0J?M2>XBKhtO{*V_-Jv;Q%GqFLoo_9Ng;h7%C{(Q)dK#pF2>La{U^0Od0HiA4E&LU4Erc@S4*>q7KuSV<^? zv0Oh<9&}s;9^rkz5R%lgdtlBTe*?KeT>Y1@K6~=oVXkl+8OOXYz{G7=I6^p*31&_P z@9q)!a1l;;L3Dv*BSA5UcCS*pvF0!_<>9TLl~TGvt$xjL_dy_?2>!z&oL-kInC%&g zKco`#D-;S}#EF$}50kt!nOz{g#!<+e%$cL8lv{1t;C`743x;8qG*5{n*W4*1VpNK{ zY%!ac)0;YiN56F|=tI|#n_p^OZN&F)>2Ai2lR6wKB3)@1vy0%21648^_yCJri_3yC z=N~$uNeL1Qtp&)aomO89VWC`NQsQhXE>M>|Gcuc zr}G&MMUyAFYJ*Ot=L})NDKG{?Nq1g@+dIqCN}MK+Icpv|{>Fo8EbvdK`XaI7J%Tq} zGHeQ>cY4`tRPba$Z7;JAbs*Ii0@0|>*`6I9au7+VEimROR9UmXyUa%i>UrET3KG*E zpSG3%6ZXniKC#9Y`dWNEtnFR%DgI>meX>~3bZg4l(Y-`eKmN0i;e8G;O4Gu4qHsgR zh7w|4C>ZD$3&9#ixkjD3YP(xto7v$@T)(h$ky41RYY=9bxZd<=<&!?FViPXIWUAaG z`iC{Wa_};A!^j<^Uh?Sm@JO%zJR4l7yzDR$={J4JB@3jMT$Hp`8Qty|;+3A{E`cLgAa8kK^tDKVrpgMsMk%|OSN z(=rVkU>&02n&>|;vD?dC0fmH;+@lD~En}GaCS$i4s$pppV^Y&VPUSlfBAVs=n^w+s zgkw(0vqOh&0QU`o`B))#!u&xSo&L+T>ynY8Ns=zq6uo(uHol)wQAS8Qmd1liwXmR; z$aWB>Hg_Ho89&*kDcD62Ns+s*WpS%XyH)IzO&}&`AnnxOqc=OFr0}zI=dB#0v0U|#r8rjJ z>ra1$JPNIOvan_}P`P=az@wTctJqM`>Tne<{{S7RfJQm3ZN z`iIE3P0j~eg0xKx`(Y7kU>Ae%8IH&=at!+rJH&^`s49&1WR*~QEj@EI0EQ#%a%0#=tM8+!YGMWUl=J3?s}w7) zpFoeUiGLMIzOHYXEKlZ3A9RWZm-x!TKHYwT+C0+I;+ltq)4jdP56=SjvsHAY*`UPs zo>B!ZLE~57Fcbl`kSG2QKihYSyF;Pb_>i3wHi!I>7NLx>syI#jjTD(?wfv?sGigvL zoJR#R&y7H9>3X_q%F7gUu-ZN-3ULgLhoY6LC4ETSL7EPI8g;d5`RL**KHK2K#Zqq1 zHr7tWJr{)qZF0(o$8L)ZmLzm5Ca5oRs4K{}JxliH8lUU?sY6sN6d@?8V)(Ff4?aWC zzFlPjMek_P^SC{y^Z6?tQD&ain1x+B=(jegwCG0OT}{}kuBY*vor25^v$Kj$djJ+Y zaivL}R~Cm-euu50?$N3{xb|G|b60I+K-44B*d%6+RH|ra8|qBNM0vo)Kw8qh8!IOK`pP(Q>UBrai~MgJ_$0P`+zq~e(|y^0>&l83yHegO zNP{|X1BF~Uk&dm+3KZs$_B7Av=u|WA_Fw9D!aJ^vN*KoRw%(qC7tM-lDUAZS@!so;f3a_IQ<6B4jfYvjZS!t>>np0k?N zxL7@?`PzZHP3xcjzH@Fo@zn1)E^@ z!I}C4b;=S_$b(zo3c0M|+Y{Wo0wv6au1scfrl8@!i-g$^@pD(u4S9^{TZn^1QUKTm ziMu*1VTE^=6xepl$(`d8*iL(7SIY7D?>0B)UlW|WQXqQfrLa6I-!w==#jQQtf)(B& zT77>YTEVciVK>djX(!+XJ1DuJ`Fi34zerfAT0l13RxWpBSYMhg^DrM^qWDQST_-e9 z_EK4HFPpAv*-cKabvZ@!fBWKmG697p{e8}A?_9i|$#SoHp6VsJusqBd4}ndA2mOs& z=xge2_t~TKN_U9Bpv$aO_OQf(VU>aSNR@}{%Uz@tzI46P&o()IdeW6U0m|~b@SF;? z-gBnf_GOmYbueF=ZLbM&`Ur2|Rrhz75ZyX1XT})BPURlm_0WO%oK5aCCog~`YYvBF z312fCM{zVya7p-WL8}7m)KQ=T2^rNKWnYj?oAIP9^?}>{FYOY)-2N2cD zn2hB!wh9YZ@Y}c|6xr$p=J+tfHSx{~9b9hU|0FDCVr2T?7>kA6TrC}(DXAD#tz2!* ze$Fax#@1#gu0K~I&SplgKW(x`s%Dx14=YzofTfqCnX|K*Il$4##Ky?NjEX_g*}>G! z#LSt}(bW9MjE;$(m64u_m5M>e%*(^U+0=!S3g*8?vU0E&HF7lrP>OOhGcs{9vNCcp zaWQeSGSV?}P%tu5{MgAknEt;^RGp0+9nDMu4B|$%E@m(cimGCo^x|%|w#G*G_GZoi zN>xiM7r@W)U;fYn)Xkh-ex?Sn{CLI0#>LD|$4t-m-){bx|J<6amAe_>$0rslfQ_S( ztEG#X5y1U_bz`SzqGzIl;pYdK*_%2TTf_YCbkC|k;Q%lw7+b5j+QBf$130;07{sld zU0ea|9IXFM_zYlSVrKcDB+r2VwA#Av!AhHTwH%*Z3pAIaiy)} zve}B_zgpKT>k~Z%B!D9^S;{PH zNmg4Iha4Ya7VWxNB5hAmR;$x=LPoa{EH2dqdi$1^$vaW9jLn|1j86~<`q~PTG?*-& z3)Tuzk@9aQqg7dusP=3#7{B2{Uo<}ijv+kve72!5Lf@aesi8hx8gnR)I16Y2ap}y| zKnoxpY#DHipe6|HzyqdPlo!6oWTZGH2F7N^J3+}@rJKwQf^85a%Hg!%T!XA$ z@YF)NZKmGk&c8N%K7plxDqcq5+&!=b%s$1wi7Y-7?dTSil8&1sZJR7+A#@<$rl%d* z^=<3WQ%ma(4RvN~>hcpHO zBIcer8~vkDI{LQ!&fbYbS`eT`<%uAWunv7Fq2(l0)YS$0y??X$lYlo^<=SV3rr7!m z2&^AiKnnA1+c%Y-5+^i!^_&y;`gC`lOASjCgZ9-p5aGm9DqY%GZMTL<;Oj0cIE0N} z+OW2%>-^C;4-1dpNlD=hY7L9Z)il^7HM-AspLe+h09j3%DLh0c-^cwN# z)1SSgZe8PNU}HyE%(j~|?fmE>KcDPKTB^=XuTaE0eqS=7QV~U;Hb?eNFg14-Sg@mq zQRtgH-2?aP&rkUK0Z3B!*5FOX-%*}q2(zRgD%%Eqm}xB5j}*BQ37Qy8ghn@14Mf?; zwn;*O3@Wrva&Dv4wuE$81ewg71?KIM(iLS`6DMp583RM~lvFx*EmD{dALfFD$jWXm zDP(;DD+vsEjTFQ3()x$QYb!-Kh{=*RL^GEJv5vVOnf44(BuN1g+*WgfB(`5yDH=dh zd^D(-?;qUEq7-~7>Iv)800qaraEDl*%-babz&e0+$4!~ z9IA@U3@l2AoQCYk2eU06gjBbUSObR71jcZd(AQy3r5XNttt^OLT3wqlIjlerEB=xJ zUhHqr#5(??UW%;KfwhCV&=3Q*k|TiD-2p>Vh8U25P4N#ogm=eg%rlPW?719kptK zb0rE}eo9nM8P!0#RF7Gf;Y-qoqerxoa66u2^OKcx5L$pYL8P)}1e*|CdqNUhn_sTv zydMF<@=|BGm2g8Xhk^C}h3%ZJMwip6$%g0OKjevP~93f2gt z`3^A(+lu%tF;RWY)=&U3k_^Kp7X>kj>Lv-7w>&U9X>LtIqCCE-rD%D9h=XURqwsX} zAK||fC#F8@5)v_sC0lIVBEB_NX3(?Gaj*RqjN%Gh}3I7!NK+51YI*qL~CChAlp z#YzeM77adl5YSFMnW*HTcf5##%2G$LF}EQ5RBqL;2;mP68TE-~auL z`?>=MrIqDGI0tOKfrBvsk%$3QEyXBRQffwZpIAYBai~VM-Jp}oX%Pt$1ui|mIeINx zSC$OceWQg6II)3}MSTOlg7Ugkz}Skq`Z(KFXCa&y}`F+8tbg&M7$DXibp^+S{G^5WK>Wy8XADvrYy zo1Nadu8;ahIUn*BJ!R`4gs}!rJ58MC0B4#duIIU4KZG@?hkJ35%p-OYnw62*p*DRK zC~S*+OVA<|DdEQ75%BdCQ4wSAvd9e9YAq4qgxqRZTN)X0E6fF>;nw(fsR@>Q6}o;@ z&I*fLrG7<{l!_1|V?R`>=9D1Yib|@Hmf}49C6X@@0U#Sen5zTvNPiJZzFq)7;AaZ3{A)}k^6U}y6YN}&SS#j&7;`T=U{T>&vWS@YM1#k0&1KufYFQTclG3DOLx$N||*&QL>b^Z8M9(N!4AiSdy&Z{**>?%VDs;kN?! zEKe+Xf|2XLug%3a1{!gN2t!wag7{U&Xo@a;(m$phF!|>?BgAGoi;A|KX~y`!i{vWR z8|D5I2<%0CatRzT2;Mq;X7-*qyy|?%_nuM!K0*JD1)N%---)tA&GeMYq&J0c`KHrD zlQYBW>&`BwVg|T%uq5nXKYX8_*3E2e+0}~=b>g41IzgVUR1W8zIa73QRj_SwZ5PQ` zvbz!D*i>I7mhY!niA`oK5BXlHsBCIQ5WiqW>;K{W{5(I)NT9H|312*S%ss}1mz80z zr-po%Zj+4Gqrh25kQ%9GVI(fQ)230!#mZXw7|E43k+v|oZ|M=pm9P0h)k3lgUcis02`O(QUJHIt8-iec#;Hm7S z7(7IsuqInwU52x-f6^J-tdASjC6K}|Lggj!!7EcZVjT!<;$j7eyf`ZxrGFqNpN+`M z;AJu)(qjsMRyNd{ASYjp#u2pcl4<{em9x{T>gnol6;FD|R)A0O0oTJ<2_t51NNU1n zpb7-Wus>loR|QD$Jb-@duolL%Iow233C|XR3{6zC0u?1_3Kw4L za=*&1ZN0;9*MBLs> z3+>tr01$NO54t3+8Qfgw1VdRGHdof7G4UUd*G1#hbj9gm!rLb(w=wD{t$e~ z;Xs**-j{0kF5PI2oCQM8#M*#aTGSg@jqe zSoi_|ZUmu6VgN zd>^CM4uaaYudExSGgnh?@y*LM&XHw$FSXzR0B5c;6`k(q!vbSO^gs$?huX&|nnRFr z1jV0&o^*uQLkdA}54JxGLeUjwc_FV#?MsX3_V7ChCFF*Fx#m z*vYc_yG>wJ^t;Ob$F8luKJTUN^R4;6Dn758wa=12 \catcode`\(=12 \catcode`\)=12 \catcode`\[=12 +\catcode`\]=12 \catcode`\==12 \catcode`\|=12} +% Sets the category codes for numbers to their normal values. +% For local use with argument scanning. +\def\IEEEnormalcatcodesnum{\catcode`\0=12 \catcode`\1=12 \catcode`\2=12 +\catcode`\3=12 \catcode`\4=12 \catcode`\5=12 \catcode`\6=12 \catcode`\7=12 +\catcode`\8=12 \catcode`\9=12} +% combined action of \IEEEnormalcatcodespunct and \IEEEnormalcatcodesnum +\def\IEEEnormalcatcodes{\IEEEnormalcatcodespunct\IEEEnormalcatcodesnum} + + +% usage: \@IEEEextracttoken*{} +% \@IEEEextracttoken fully expands its argument (which it then stores in +% \@IEEEextracttokenarg) via \edef and then the meaning of the first +% nonbrace (but including the empty group) token found is assigned via \let +% to \@IEEEextractedtoken as well as stored in the macro +% \@IEEEextractedtokenmacro. Tokens that would otherwise be discarded during +% the acquisition of the first are stored in \@IEEEextractedtokensdiscarded, +% however their original relative brace nesting depths are not guaranteed to +% be preserved. +% If the argument is empty, or if a first nonbrace token does not exist (or +% is an empty group), \@IEEEextractedtoken will be \relax and +% \@IEEEextractedtokenmacro and \@IEEEextractedtokensdiscarded will be empty. +% +% For example: +% \@IEEEextracttoken{{{ab}{cd}}{{ef}g}} +% results in: +% +% \@IEEEextracttokenarg ==> a macro containing {{ab}{cd}}{{ef}g} +% \@IEEEextractedtoken ==> the letter a +% \@IEEEextractedtokenmacro ==> a macro containing a +% \@IEEEextractedtokensdiscarded ==> a macro containing bcd{ef}g +% +% the *-star form, \@IEEEextracttoken*, does not expand its argument +% contents during processing. +\def\@IEEEextracttoken{\@ifstar{\let\@IEEEextracttokendef=\def\@@IEEEextracttoken}{\let\@IEEEextracttokendef=\edef\@@IEEEextracttoken}} + +\def\@@IEEEextracttoken#1{\@IEEEextracttokendef\@IEEEextracttokenarg{#1}\relax +\def\@IEEEextractedtokensdiscarded{}\relax % initialize to empty +% if the macro is unchanged after being acquired as a single undelimited argument +% with anything after it being stripped off as a delimited argument +% we know we have one token without any enclosing braces. loop until this is true. +\let\@IEEEextracttokencurgroup\@IEEEextracttokenarg +\loop + % trap case of an empty argument as this would cause a problem with + % \@@@IEEEextracttoken's first (nondelimited) argument acquisition + \ifx\@IEEEextracttokencurgroup\@empty + \def\@IEEEextractedtokenmacro{}\relax + \else + \expandafter\@@@IEEEextracttoken\@IEEEextracttokencurgroup\@IEEEgeneralsequenceDELIMITER\relax + \fi + \ifx\@IEEEextractedtokenmacro\@IEEEextracttokencurgroup + \else + \let\@IEEEextracttokencurgroup=\@IEEEextractedtokenmacro +\repeat +% we can safely do a \let= here because there should be at most one token +% the relax is needed to handle the case of no token found +\expandafter\let\expandafter\@IEEEextractedtoken\@IEEEextractedtokenmacro\relax} + +\def\@@@IEEEextracttoken#1#2\@IEEEgeneralsequenceDELIMITER{\def\@IEEEextractedtokenmacro{#1}\relax +\def\@@IEEEextractedtokensdiscarded{#2}\expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter +\@IEEEextractedtokensdiscarded\expandafter\expandafter\expandafter +{\expandafter\@@IEEEextractedtokensdiscarded\@IEEEextractedtokensdiscarded}} +%% +%% -- End of Command Argument Scanning Support Functions -- + + + +% Computer Society conditional execution command +\long\def\@IEEEcompsoconly#1{\relax\ifCLASSOPTIONcompsoc\relax#1\relax\fi\relax} +% inverse +\long\def\@IEEEnotcompsoconly#1{\relax\ifCLASSOPTIONcompsoc\else\relax#1\relax\fi\relax} +% compsoc conference +\long\def\@IEEEcompsocconfonly#1{\relax\ifCLASSOPTIONcompsoc\ifCLASSOPTIONconference\relax#1\relax\fi\fi\relax} +% compsoc not conference +\long\def\@IEEEcompsocnotconfonly#1{\relax\ifCLASSOPTIONcompsoc\ifCLASSOPTIONconference\else\relax#1\relax\fi\fi\relax} + + +% comsoc verify that newtxmath, mtpro2, mt11p or mathtime has been loaded +\def\@IEEEcomsocverifymathfont{\typeout{-- Verifying Times compatible math font.}\relax + \@ifpackageloaded{newtxmath}{\typeout{-- newtxmath loaded, OK.}}{\@@IEEEcomsocverifymathfont}} +\def\@@IEEEcomsocverifymathfont{\@ifpackageloaded{mtpro2}{\typeout{-- mtpro2 loaded, OK.}}{\@@@IEEEcomsocverifymathfont}} +\def\@@@IEEEcomsocverifymathfont{\@ifpackageloaded{mt11p}{\typeout{-- mt11p2 loaded, OK.}}{\@@@@IEEEcomsocverifymathfont}} +\def\@@@@IEEEcomsocverifymathfont{\@ifpackageloaded{mathtime}{\typeout{-- mathtime loaded, OK.}}{\@IEEEcomsocenforcemathfont}} + +% comsoc, if a Times math font was not loaded by user, enforce it +\def\@IEEEcomsocenforcemathfont{\typeout{** Times compatible math font not found, forcing.}\relax +\IfFileExists{newtxmath.sty}{\typeout{-- Found newtxmath, loading.}\RequirePackage{newtxmath}}{\@@IEEEcomsocenforcemathfont}} +\def\@@IEEEcomsocenforcemathfont{\IfFileExists{mtpro2.sty}{\typeout{-- Found mtpro2, loading.}\RequirePackage{mtpro2}}{\@@@IEEEcomsocenforcemathfont}} +\def\@@@IEEEcomsocenforcemathfont{\IfFileExists{mt11p.sty}{\typeout{-- Found mt11p, loading.}\RequirePackage{mt11p}}{\@@@@IEEEcomsocenforcemathfont}} +\def\@@@@IEEEcomsocenforcemathfont{\IfFileExists{mathtime.sty}{\typeout{-- Found mathtime, loading.}\RequirePackage{mathtime}}{\@@@@@IEEEcomsocenforcemathfont}} +% if no acceptable Times math font package found, error with newtxmath requirement +\def\@@@@@IEEEcomsocenforcemathfont{\typeout{** No Times compatible math font package found. newtxmath is required.}\RequirePackage{newtxmath}} + + +\ifCLASSOPTIONcomsoc + % ensure that if newtxmath is used, the cmintegrals option is also invoked + \PassOptionsToPackage{cmintegrals}{newtxmath} + % comsoc requires a Times like math font + % ensure this requirement is satisfied at document start + \AtBeginDocument{\@IEEEcomsocverifymathfont} +\fi + + + +% The IEEE uses Times Roman font, so we'll default to Times. +% These three commands make up the entire times.sty package. +\renewcommand{\sfdefault}{phv} +\renewcommand{\rmdefault}{ptm} +\renewcommand{\ttdefault}{pcr} + +% V1.7 compsoc nonconference papers, use Palatino/Palladio as the main text font, +% not Times Roman. +\@IEEEcompsocnotconfonly{\renewcommand{\rmdefault}{ppl}} + +% enable the selected main text font +\normalfont\selectfont + + +\ifCLASSOPTIONcomsoc + \typeout{-- Using IEEE Communications Society mode.} +\fi + +\ifCLASSOPTIONcompsoc + \typeout{-- Using IEEE Computer Society mode.} +\fi + + +% V1.7 conference notice message hook +\def\@IEEEconsolenoticeconference{\typeout{}% +\typeout{** Conference Paper **}% +\typeout{Before submitting the final camera ready copy, remember to:}% +\typeout{}% +\typeout{ 1. Manually equalize the lengths of two columns on the last page}% +\typeout{ of your paper;}% +\typeout{}% +\typeout{ 2. Ensure that any PostScript and/or PDF output post-processing}% +\typeout{ uses only Type 1 fonts and that every step in the generation}% +\typeout{ process uses the appropriate paper size.}% +\typeout{}} + + +% we can send console reminder messages to the user here +\AtEndDocument{\ifCLASSOPTIONconference\@IEEEconsolenoticeconference\fi} + + +% warn about the use of single column other than for draft mode +\ifCLASSOPTIONtwocolumn\else% + \ifCLASSOPTIONdraftcls\else% + \typeout{** ATTENTION: Single column mode is not typically used with IEEE publications.}% + \fi% +\fi + + +% V1.7 improved paper size setting code. +% Set pdfpage and dvips paper sizes. Conditional tests are similar to that +% of ifpdf.sty. Retain within {} to ensure tested macros are never altered, +% even if only effect is to set them to \relax. +% if \pdfoutput is undefined or equal to relax, output a dvips special +{\@ifundefined{pdfoutput}{\AtBeginDvi{\special{papersize=\CLASSINFOpaperwidth,\CLASSINFOpaperheight}}}{% +% pdfoutput is defined and not equal to \relax +% check for pdfpageheight existence just in case someone sets pdfoutput +% under non-pdflatex. If exists, set them regardless of value of \pdfoutput. +\@ifundefined{pdfpageheight}{\relax}{\global\pdfpagewidth\paperwidth +\global\pdfpageheight\paperheight}% +% if using \pdfoutput=0 under pdflatex, send dvips papersize special +\ifcase\pdfoutput +\AtBeginDvi{\special{papersize=\CLASSINFOpaperwidth,\CLASSINFOpaperheight}}% +\else +% we are using pdf output, set CLASSINFOpdf flag +\global\CLASSINFOpdftrue +\fi}} + +% let the user know the selected papersize +\typeout{-- Using \CLASSINFOpaperwidth\space x \CLASSINFOpaperheight\space +(\CLASSOPTIONpaper)\space paper.} + +\ifCLASSINFOpdf +\typeout{-- Using PDF output.} +\else +\typeout{-- Using DVI output.} +\fi + + +% The idea hinted here is for LaTeX to generate markleft{} and markright{} +% automatically for you after you enter \author{}, \journal{}, +% \journaldate{}, journalvol{}, \journalnum{}, etc. +% However, there may be some backward compatibility issues here as +% well as some special applications for IEEEtran.cls and special issues +% that may require the flexible \markleft{}, \markright{} and/or \markboth{}. +% We'll leave this as an open future suggestion. +%\newcommand{\journal}[1]{\def\@journal{#1}} +%\def\@journal{} + + + +% pointsize values +% used with ifx to determine the document's normal size +\def\@IEEEptsizenine{9} +\def\@IEEEptsizeten{10} +\def\@IEEEptsizeeleven{11} +\def\@IEEEptsizetwelve{12} + + + +% FONT DEFINITIONS (No sizexx.clo file needed) +% V1.6 revised font sizes, displayskip values and +% revised normalsize baselineskip to reduce underfull vbox problems +% on the 58pc = 696pt = 9.5in text height we want +% normalsize #lines/column baselineskip (aka leading) +% 9pt 63 11.0476pt (truncated down) +% 10pt 58 12pt (exact) +% 11pt 52 13.3846pt (truncated down) +% 12pt 50 13.92pt (exact) +% + +% we need to store the nominal baselineskip for the given font size +% in case baselinestretch ever changes. +% this is a dimen, so it will not hold stretch or shrink +\newdimen\@IEEEnormalsizeunitybaselineskip +\@IEEEnormalsizeunitybaselineskip\baselineskip + + + +%% ******* WARNING! ******* +%% +%% Authors should not alter font sizes, baselineskip ("leading"), +%% margins or other spacing values in an attempt to squeeze more +%% material on each page. +%% +%% The IEEE's own typesetting software will restore the correct +%% values when re-typesetting/proofing the submitted document, +%% possibly resulting in unexpected article over length charges. +%% +%% ******* WARNING! ******* + + +% 9pt option defaults +\ifx\CLASSOPTIONpt\@IEEEptsizenine +\typeout{-- This is a 9 point document.} +\def\normalsize{\@setfontsize{\normalsize}{9}{11.0476pt}} +\setlength{\@IEEEnormalsizeunitybaselineskip}{11.0476pt} +\normalsize +\abovedisplayskip 1.5ex plus 3pt minus 1pt +\belowdisplayskip \abovedisplayskip +\abovedisplayshortskip 0pt plus 3pt +\belowdisplayshortskip 1.5ex plus 3pt minus 1pt +\def\small{\@setfontsize{\small}{8.5}{10pt}} +\def\footnotesize{\@setfontsize{\footnotesize}{8}{9pt}} +\def\scriptsize{\@setfontsize{\scriptsize}{7}{8pt}} +\def\tiny{\@setfontsize{\tiny}{5}{6pt}} +% sublargesize is the same as large - 10pt +\def\sublargesize{\@setfontsize{\sublargesize}{10}{12pt}} +\def\large{\@setfontsize{\large}{10}{12pt}} +\def\Large{\@setfontsize{\Large}{12}{14pt}} +\def\LARGE{\@setfontsize{\LARGE}{14}{17pt}} +\def\huge{\@setfontsize{\huge}{17}{20pt}} +\def\Huge{\@setfontsize{\Huge}{20}{24pt}} +\fi +% +% 10pt option defaults +\ifx\CLASSOPTIONpt\@IEEEptsizeten +\typeout{-- This is a 10 point document.} +\def\normalsize{\@setfontsize{\normalsize}{10}{12.00pt}} +\setlength{\@IEEEnormalsizeunitybaselineskip}{12pt} +\normalsize +\abovedisplayskip 1.5ex plus 4pt minus 2pt +\belowdisplayskip \abovedisplayskip +\abovedisplayshortskip 0pt plus 4pt +\belowdisplayshortskip 1.5ex plus 4pt minus 2pt +\def\small{\@setfontsize{\small}{9}{10pt}} +\def\footnotesize{\@setfontsize{\footnotesize}{8}{9pt}} +\def\scriptsize{\@setfontsize{\scriptsize}{7}{8pt}} +\def\tiny{\@setfontsize{\tiny}{5}{6pt}} +% sublargesize is a tad smaller than large - 11pt +\def\sublargesize{\@setfontsize{\sublargesize}{11}{13.4pt}} +\def\large{\@setfontsize{\large}{12}{14pt}} +\def\Large{\@setfontsize{\Large}{14}{17pt}} +\def\LARGE{\@setfontsize{\LARGE}{17}{20pt}} +\def\huge{\@setfontsize{\huge}{20}{24pt}} +\def\Huge{\@setfontsize{\Huge}{24}{28pt}} +\fi +% +% 11pt option defaults +\ifx\CLASSOPTIONpt\@IEEEptsizeeleven +\typeout{-- This is an 11 point document.} +\def\normalsize{\@setfontsize{\normalsize}{11}{13.3846pt}} +\setlength{\@IEEEnormalsizeunitybaselineskip}{13.3846pt} +\normalsize +\abovedisplayskip 1.5ex plus 5pt minus 3pt +\belowdisplayskip \abovedisplayskip +\abovedisplayshortskip 0pt plus 5pt +\belowdisplayshortskip 1.5ex plus 5pt minus 3pt +\def\small{\@setfontsize{\small}{10}{12pt}} +\def\footnotesize{\@setfontsize{\footnotesize}{9}{10.5pt}} +\def\scriptsize{\@setfontsize{\scriptsize}{8}{9pt}} +\def\tiny{\@setfontsize{\tiny}{6}{7pt}} +% sublargesize is the same as large - 12pt +\def\sublargesize{\@setfontsize{\sublargesize}{12}{14pt}} +\def\large{\@setfontsize{\large}{12}{14pt}} +\def\Large{\@setfontsize{\Large}{14}{17pt}} +\def\LARGE{\@setfontsize{\LARGE}{17}{20pt}} +\def\huge{\@setfontsize{\huge}{20}{24pt}} +\def\Huge{\@setfontsize{\Huge}{24}{28pt}} +\fi +% +% 12pt option defaults +\ifx\CLASSOPTIONpt\@IEEEptsizetwelve +\typeout{-- This is a 12 point document.} +\def\normalsize{\@setfontsize{\normalsize}{12}{13.92pt}} +\setlength{\@IEEEnormalsizeunitybaselineskip}{13.92pt} +\normalsize +\abovedisplayskip 1.5ex plus 6pt minus 4pt +\belowdisplayskip \abovedisplayskip +\abovedisplayshortskip 0pt plus 6pt +\belowdisplayshortskip 1.5ex plus 6pt minus 4pt +\def\small{\@setfontsize{\small}{10}{12pt}} +\def\footnotesize{\@setfontsize{\footnotesize}{9}{10.5pt}} +\def\scriptsize{\@setfontsize{\scriptsize}{8}{9pt}} +\def\tiny{\@setfontsize{\tiny}{6}{7pt}} +% sublargesize is the same as large - 14pt +\def\sublargesize{\@setfontsize{\sublargesize}{14}{17pt}} +\def\large{\@setfontsize{\large}{14}{17pt}} +\def\Large{\@setfontsize{\Large}{17}{20pt}} +\def\LARGE{\@setfontsize{\LARGE}{20}{24pt}} +\def\huge{\@setfontsize{\huge}{22}{26pt}} +\def\Huge{\@setfontsize{\Huge}{24}{28pt}} +\fi + + + +% V1.8a compsoc font sizes +% compsoc font sizes use bp "Postscript" point units (1/72in) +% rather than the traditional pt (1/72.27) +\ifCLASSOPTIONcompsoc +% -- compsoc defaults -- +% ** will override some of these values later ** +% 9pt +\ifx\CLASSOPTIONpt\@IEEEptsizenine +\def\normalsize{\@setfontsize{\normalsize}{9bp}{11bp}} +\setlength{\@IEEEnormalsizeunitybaselineskip}{11bp} +\normalsize +\abovedisplayskip 1.5ex plus 3bp minus 1bp +\belowdisplayskip \abovedisplayskip +\abovedisplayshortskip 0bp plus 3bp +\belowdisplayshortskip 1.5ex plus 3bp minus 1bp +\def\small{\@setfontsize{\small}{8.5bp}{10bp}} +\def\footnotesize{\@setfontsize{\footnotesize}{8bp}{9bp}} +\def\scriptsize{\@setfontsize{\scriptsize}{7bp}{8bp}} +\def\tiny{\@setfontsize{\tiny}{5bp}{6bp}} +% sublargesize is the same as large - 10bp +\def\sublargesize{\@setfontsize{\sublargesize}{10bp}{12bp}} +\def\large{\@setfontsize{\large}{10bp}{12bp}} +\def\Large{\@setfontsize{\Large}{12bp}{14bp}} +\def\LARGE{\@setfontsize{\LARGE}{14bp}{17bp}} +\def\huge{\@setfontsize{\huge}{17bp}{20bp}} +\def\Huge{\@setfontsize{\Huge}{20bp}{24bp}} +\fi +% +% 10pt +\ifx\CLASSOPTIONpt\@IEEEptsizeten +\def\normalsize{\@setfontsize{\normalsize}{10bp}{12bp}} +\setlength{\@IEEEnormalsizeunitybaselineskip}{12bp} +\normalsize +\abovedisplayskip 1.5ex plus 4bp minus 2bp +\belowdisplayskip \abovedisplayskip +\abovedisplayshortskip 0pt plus 4bp +\belowdisplayshortskip 1.5ex plus 4bp minus 2bp +\def\small{\@setfontsize{\small}{9bp}{10bp}} +\def\footnotesize{\@setfontsize{\footnotesize}{8bp}{9bp}} +\def\scriptsize{\@setfontsize{\scriptsize}{7bp}{8bp}} +\def\tiny{\@setfontsize{\tiny}{5bp}{6bp}} +% sublargesize is a tad smaller than large - 11bp +\def\sublargesize{\@setfontsize{\sublargesize}{11bp}{13.5bp}} +\def\large{\@setfontsize{\large}{12bp}{14bp}} +\def\Large{\@setfontsize{\Large}{14bp}{17bp}} +\def\LARGE{\@setfontsize{\LARGE}{17bp}{20bp}} +\def\huge{\@setfontsize{\huge}{20bp}{24bp}} +\def\Huge{\@setfontsize{\Huge}{24bp}{28bp}} +\fi +% +% 11pt +\ifx\CLASSOPTIONpt\@IEEEptsizeeleven +\def\normalsize{\@setfontsize{\normalsize}{11bp}{13.5bp}} +\setlength{\@IEEEnormalsizeunitybaselineskip}{13.5bp} +\normalsize +\abovedisplayskip 1.5ex plus 5bp minus 3bp +\belowdisplayskip \abovedisplayskip +\abovedisplayshortskip 0pt plus 5bp +\belowdisplayshortskip 1.5ex plus 5bp minus 3bp +\def\small{\@setfontsize{\small}{10bp}{12bp}} +\def\footnotesize{\@setfontsize{\footnotesize}{9bp}{10.5bp}} +\def\scriptsize{\@setfontsize{\scriptsize}{8bp}{9bp}} +\def\tiny{\@setfontsize{\tiny}{6bp}{7bp}} +% sublargesize is the same as large - 12bp +\def\sublargesize{\@setfontsize{\sublargesize}{12bp}{14bp}} +\def\large{\@setfontsize{\large}{12bp}{14bp}} +\def\Large{\@setfontsize{\Large}{14bp}{17bp}} +\def\LARGE{\@setfontsize{\LARGE}{17bp}{20bp}} +\def\huge{\@setfontsize{\huge}{20bp}{24bp}} +\def\Huge{\@setfontsize{\Huge}{24bp}{28bp}} +\fi +% +% 12pt +\ifx\CLASSOPTIONpt\@IEEEptsizetwelve +\def\normalsize{\@setfontsize{\normalsize}{12bp}{14bp}}% +\setlength{\@IEEEnormalsizeunitybaselineskip}{14bp}% +\normalsize +\abovedisplayskip 1.5ex plus 6bp minus 4bp +\belowdisplayskip \abovedisplayskip +\abovedisplayshortskip 0pt plus 6bp +\belowdisplayshortskip 1.5ex plus 6bp minus 4bp +\def\small{\@setfontsize{\small}{10bp}{12bp}} +\def\footnotesize{\@setfontsize{\footnotesize}{9bp}{10.5bp}} +\def\scriptsize{\@setfontsize{\scriptsize}{8bp}{9bp}} +\def\tiny{\@setfontsize{\tiny}{6bp}{7bp}} +% sublargesize is the same as large - 14bp +\def\sublargesize{\@setfontsize{\sublargesize}{14bp}{17bp}} +\def\large{\@setfontsize{\large}{14bp}{17bp}} +\def\Large{\@setfontsize{\Large}{17bp}{20bp}} +\def\LARGE{\@setfontsize{\LARGE}{20bp}{24bp}} +\def\huge{\@setfontsize{\huge}{22bp}{26bp}} +\def\Huge{\@setfontsize{\Huge}{24bp}{28bp}} +\fi +% +% -- override defaults: compsoc journals use special normalsizes -- +\ifCLASSOPTIONconference +% +% compsoc conferences +% 9pt +\ifx\CLASSOPTIONpt\@IEEEptsizenine +\def\normalsize{\@setfontsize{\normalsize}{9bp}{10.8bp}} +\setlength{\@IEEEnormalsizeunitybaselineskip}{10.8bp} +\normalsize +\abovedisplayskip 1.5ex plus 3bp minus 1bp +\belowdisplayskip \abovedisplayskip +\abovedisplayshortskip 0bp plus 3bp +\belowdisplayshortskip 1.5ex plus 3bp minus 1bp +\fi +% 10pt +\ifx\CLASSOPTIONpt\@IEEEptsizeten +\def\normalsize{\@setfontsize{\normalsize}{10bp}{11.2bp}} +\setlength{\@IEEEnormalsizeunitybaselineskip}{11.2bp} +\normalsize +\abovedisplayskip 1.5ex plus 4bp minus 2bp +\belowdisplayskip \abovedisplayskip +\abovedisplayshortskip 0pt plus 4bp +\belowdisplayshortskip 1.5ex plus 4bp minus 2bp +\fi +% 11pt +\ifx\CLASSOPTIONpt\@IEEEptsizeeleven +\def\normalsize{\@setfontsize{\normalsize}{11bp}{13.2bp}} +\setlength{\@IEEEnormalsizeunitybaselineskip}{13.2bp} +\normalsize +\abovedisplayskip 1.5ex plus 5bp minus 3bp +\belowdisplayskip \abovedisplayskip +\abovedisplayshortskip 0pt plus 5bp +\belowdisplayshortskip 1.5ex plus 5bp minus 3bp +\fi +% 12pt +\ifx\CLASSOPTIONpt\@IEEEptsizetwelve +\def\normalsize{\@setfontsize{\normalsize}{12bp}{14.4bp}} +\setlength{\@IEEEnormalsizeunitybaselineskip}{14.4bp} +\normalsize +\abovedisplayskip 1.5ex plus 6bp minus 4bp +\belowdisplayskip \abovedisplayskip +\abovedisplayshortskip 0pt plus 6bp +\belowdisplayshortskip 1.5ex plus 6bp minus 4bp +\fi +% +% compsoc nonconferences +\else +% 9pt +\ifx\CLASSOPTIONpt\@IEEEptsizenine +\def\normalsize{\@setfontsize{\normalsize}{9bp}{10.8bp}} +\setlength{\@IEEEnormalsizeunitybaselineskip}{10.8bp} +\normalsize +\abovedisplayskip 1.5ex plus 3bp minus 1bp +\belowdisplayskip \abovedisplayskip +\abovedisplayshortskip 0bp plus 3bp +\belowdisplayshortskip 1.5ex plus 3bp minus 1bp +\fi +% 10pt +\ifx\CLASSOPTIONpt\@IEEEptsizeten +% the official spec is 9.5bp with 11.4bp leading for 10pt, +% but measurements of proofs suggest upto 11.723bp leading +% here we'll use 11.54bp which gives 61 lines per column +% with the standard compsoc margins +\def\normalsize{\@setfontsize{\normalsize}{9.5bp}{11.54bp}} +\setlength{\@IEEEnormalsizeunitybaselineskip}{11.54bp} +\normalsize +\abovedisplayskip 1.5ex plus 4bp minus 2bp +\belowdisplayskip \abovedisplayskip +\abovedisplayshortskip 0pt plus 4bp +\belowdisplayshortskip 1.5ex plus 4bp minus 2bp +\fi +% 11pt +\ifx\CLASSOPTIONpt\@IEEEptsizeeleven +\def\normalsize{\@setfontsize{\normalsize}{11bp}{13.2bp}} +\setlength{\@IEEEnormalsizeunitybaselineskip}{13.2bp} +\normalsize +\abovedisplayskip 1.5ex plus 5bp minus 3bp +\belowdisplayskip \abovedisplayskip +\abovedisplayshortskip 0pt plus 5bp +\belowdisplayshortskip 1.5ex plus 5bp minus 3bp +\fi +% 12pt +\ifx\CLASSOPTIONpt\@IEEEptsizetwelve +\def\normalsize{\@setfontsize{\normalsize}{12bp}{14.4bp}} +\setlength{\@IEEEnormalsizeunitybaselineskip}{14.4bp} +\normalsize +\abovedisplayskip 1.5ex plus 6bp minus 4bp +\belowdisplayskip \abovedisplayskip +\abovedisplayshortskip 0pt plus 6bp +\belowdisplayshortskip 1.5ex plus 6bp minus 4bp +\fi +\fi\fi + + + + +% V1.6 The Computer Modern Fonts will issue a substitution warning for +% 24pt titles (24.88pt is used instead, but the default and correct +% Times font will scale exactly as needed) increase the substitution +% tolerance to turn off this warning. +% +% V1.8a, the compsoc bp font sizes can also cause bogus font substitution +% warnings with footnote or scriptsize math and the $\bullet$ itemized +% list of \IEEEcompsocitemizethanks. So, increase this to 1.5pt or more. +\def\fontsubfuzz{1.7bp} + + +% warn the user in case they forget to use the 9pt option with +% technote +\ifCLASSOPTIONtechnote% + \ifx\CLASSOPTIONpt\@IEEEptsizenine\else% + \typeout{** ATTENTION: Technotes are normally 9pt documents.}% + \fi% +\fi + + +% V1.7 +% Improved \textunderscore to provide a much better fake _ when used with +% OT1 encoding. Under OT1, detect use of pcr or cmtt \ttfamily and use +% available true _ glyph for those two typewriter fonts. +\def\@IEEEstringptm{ptm} % Times Roman family +\def\@IEEEstringppl{ppl} % Palatino Roman family +\def\@IEEEstringphv{phv} % Helvetica Sans Serif family +\def\@IEEEstringpcr{pcr} % Courier typewriter family +\def\@IEEEstringcmtt{cmtt} % Computer Modern typewriter family +\DeclareTextCommandDefault{\textunderscore}{\leavevmode +\ifx\f@family\@IEEEstringpcr\string_\else +\ifx\f@family\@IEEEstringcmtt\string_\else +\ifx\f@family\@IEEEstringptm\kern 0em\vbox{\hrule\@width 0.5em\@height 0.5pt\kern -0.3ex}\else +\ifx\f@family\@IEEEstringppl\kern 0em\vbox{\hrule\@width 0.5em\@height 0.5pt\kern -0.3ex}\else +\ifx\f@family\@IEEEstringphv\kern -0.03em\vbox{\hrule\@width 0.62em\@height 0.52pt\kern -0.33ex}\kern -0.03em\else +\kern 0.09em\vbox{\hrule\@width 0.6em\@height 0.44pt\kern -0.63pt\kern -0.42ex}\kern 0.09em\fi\fi\fi\fi\fi\relax} + + + + +% set the default \baselinestretch +\def\baselinestretch{1} +\ifCLASSOPTIONdraftcls + \def\baselinestretch{1.5}% default baselinestretch for draft modes +\fi + + +% process CLASSINPUT baselinestretch +\ifx\CLASSINPUTbaselinestretch\@IEEEundefined +\else + \edef\baselinestretch{\CLASSINPUTbaselinestretch} % user CLASSINPUT override + \typeout{** ATTENTION: Overriding \string\baselinestretch\space to + \baselinestretch\space via \string\CLASSINPUT.} +\fi + +\small\normalsize % make \baselinestretch take affect + + + + +% store the normalsize baselineskip +\newdimen\CLASSINFOnormalsizebaselineskip +\CLASSINFOnormalsizebaselineskip=\baselineskip\relax +% and the normalsize unity (baselinestretch=1) baselineskip +% we could save a register by giving the user access to +% \@IEEEnormalsizeunitybaselineskip. However, let's protect +% its read only internal status +\newdimen\CLASSINFOnormalsizeunitybaselineskip +\CLASSINFOnormalsizeunitybaselineskip=\@IEEEnormalsizeunitybaselineskip\relax +% store the nominal value of jot +\newdimen\IEEEnormaljot +\IEEEnormaljot=0.25\baselineskip\relax + +% set \jot +\jot=\IEEEnormaljot\relax + + + + +% V1.6, we are now going to fine tune the interword spacing +% The default interword glue for Times under TeX appears to use a +% nominal interword spacing of 25% (relative to the font size, i.e., 1em) +% a maximum of 40% and a minimum of 19%. +% For example, 10pt text uses an interword glue of: +% +% 2.5pt plus 1.49998pt minus 0.59998pt +% +% However, the IEEE allows for a more generous range which reduces the need +% for hyphenation, especially for two column text. Furthermore, the IEEE +% tends to use a little bit more nominal space between the words. +% The IEEE's interword spacing percentages appear to be: +% 35% nominal +% 23% minimum +% 50% maximum +% (They may even be using a tad more for the largest fonts such as 24pt.) +% +% for bold text, the IEEE increases the spacing a little more: +% 37.5% nominal +% 23% minimum +% 55% maximum + +% here are the interword spacing ratios we'll use +% for medium (normal weight) +\def\@IEEEinterspaceratioM{0.35} +\def\@IEEEinterspaceMINratioM{0.23} +\def\@IEEEinterspaceMAXratioM{0.50} + +% for bold +\def\@IEEEinterspaceratioB{0.375} +\def\@IEEEinterspaceMINratioB{0.23} +\def\@IEEEinterspaceMAXratioB{0.55} + + +% compsoc nonconference papers use Palatino, +% tweak settings to better match the proofs +\ifCLASSOPTIONcompsoc +\ifCLASSOPTIONconference\else +% for medium (normal weight) +\def\@IEEEinterspaceratioM{0.28} +\def\@IEEEinterspaceMINratioM{0.21} +\def\@IEEEinterspaceMAXratioM{0.47} +% for bold +\def\@IEEEinterspaceratioB{0.305} +\def\@IEEEinterspaceMINratioB{0.21} +\def\@IEEEinterspaceMAXratioB{0.52} +\fi\fi + + +% command to revise the interword spacing for the current font under TeX: +% \fontdimen2 = nominal interword space +% \fontdimen3 = interword stretch +% \fontdimen4 = interword shrink +% since all changes to the \fontdimen are global, we can enclose these commands +% in braces to confine any font attribute or length changes +\def\@@@IEEEsetfontdimens#1#2#3{{% +\setlength{\@IEEEtrantmpdimenB}{\f@size pt}% grab the font size in pt, could use 1em instead. +\setlength{\@IEEEtrantmpdimenA}{#1\@IEEEtrantmpdimenB}% +\fontdimen2\font=\@IEEEtrantmpdimenA\relax +\addtolength{\@IEEEtrantmpdimenA}{-#2\@IEEEtrantmpdimenB}% +\fontdimen3\font=-\@IEEEtrantmpdimenA\relax +\setlength{\@IEEEtrantmpdimenA}{#1\@IEEEtrantmpdimenB}% +\addtolength{\@IEEEtrantmpdimenA}{-#3\@IEEEtrantmpdimenB}% +\fontdimen4\font=\@IEEEtrantmpdimenA\relax}} + +% revise the interword spacing for each font weight +\def\@@IEEEsetfontdimens{{% +\mdseries +\@@@IEEEsetfontdimens{\@IEEEinterspaceratioM}{\@IEEEinterspaceMAXratioM}{\@IEEEinterspaceMINratioM}% +\bfseries +\@@@IEEEsetfontdimens{\@IEEEinterspaceratioB}{\@IEEEinterspaceMAXratioB}{\@IEEEinterspaceMINratioB}% +}} + +% revise the interword spacing for each font shape +% \slshape is not often used for IEEE work and is not altered here. The \scshape caps are +% already a tad too large in the free LaTeX fonts (as compared to what the IEEE uses) so we +% won't alter these either. +\def\@IEEEsetfontdimens{{% +\normalfont +\@@IEEEsetfontdimens +\normalfont\itshape +\@@IEEEsetfontdimens +}} + +% command to revise the interword spacing for each font size (and shape +% and weight). Only the \rmfamily is done here as \ttfamily uses a +% fixed spacing and \sffamily is not used as the main text of IEEE papers. +\def\@IEEEtunefonts{{\selectfont\rmfamily +\tiny\@IEEEsetfontdimens +\scriptsize\@IEEEsetfontdimens +\footnotesize\@IEEEsetfontdimens +\small\@IEEEsetfontdimens +\normalsize\@IEEEsetfontdimens +\sublargesize\@IEEEsetfontdimens +\large\@IEEEsetfontdimens +\LARGE\@IEEEsetfontdimens +\huge\@IEEEsetfontdimens +\Huge\@IEEEsetfontdimens}} + +% if the nofonttune class option is not given, revise the interword spacing +% now - in case IEEEtran makes any default length measurements, and make +% sure all the default fonts are loaded +\ifCLASSOPTIONnofonttune\else +\@IEEEtunefonts +\fi + +% and again at the start of the document in case the user loaded different fonts +\AtBeginDocument{\ifCLASSOPTIONnofonttune\else\@IEEEtunefonts\fi} + + + + + +% -- V1.8a page setup commands -- + +% The default sample text for calculating margins +% Note that IEEE publications use \scriptsize for headers and footers. +\def\IEEEdefaultsampletext{\normalfont\normalsize gT} +\def\IEEEdefaultheadersampletext{\normalfont\scriptsize T}% IEEE headers default to uppercase +\def\IEEEdefaultfootersampletext{\normalfont\scriptsize gT} + + + +% usage: \IEEEsettextwidth{inner margin}{outer margin} +% Sets \textwidth to allow the specified inner and outer margins +% for the current \paperwidth. +\def\IEEEsettextwidth#1#2{\@IEEEtrantmpdimenA\paperwidth +\@IEEEtrantmpdimenB#1\relax +\advance\@IEEEtrantmpdimenA by -\@IEEEtrantmpdimenB +\@IEEEtrantmpdimenB#2\relax +\advance\@IEEEtrantmpdimenA by -\@IEEEtrantmpdimenB +\textwidth\@IEEEtrantmpdimenA} + + + +% usage: \IEEEsetsidemargin{mode: i, o, c, a}{margin/offset} +% Sets \oddsidemargin and \evensidemargin to yield the specified margin +% of the given mode. +% The available modes are: +% i = inner margin +% o = outer margin +% c = centered, with the given offset +% a = adjust the margins using the given offset +% For the offsets, positive values increase the inner margin. +% \textwidth should be set properly for the given margins before calling this +% function. +\def\IEEEsetsidemargin#1#2{\@IEEEtrantmpdimenA #2\relax +\@IEEEextracttoken{#1}\relax +% check for mode errors +\ifx\@IEEEextractedtokenmacro\@empty + \@IEEEclspkgerror{Empty mode type in \string\IEEEsetsidemargin\space (line \the\inputlineno).\MessageBreak + Defaulting to `i'}{Valid modes for \string\IEEEsetsidemargin\space are: i, o, c and a.}\relax + \let\@IEEEextractedtoken=i\relax + \def\@IEEEextractedtokenmacro{i}\relax +\else + \ifx\@IEEEextractedtokensdiscarded\@empty\else + \typeout{** WARNING: \string\IEEEsetsidemargin\space mode specifiers after the first in `\@IEEEextracttokenarg' ignored (line \the\inputlineno).}\relax + \fi +\fi +% handle each mode +\if\@IEEEextractedtoken a\relax + \advance\oddsidemargin by \@IEEEtrantmpdimenA\relax +\else +\if\@IEEEextractedtoken c\relax + \oddsidemargin\paperwidth + \advance\oddsidemargin by -\textwidth + \divide\oddsidemargin by 2\relax + \advance\oddsidemargin by -1in\relax + \advance\oddsidemargin by \@IEEEtrantmpdimenA\relax +\else +\if\@IEEEextractedtoken o\relax + \oddsidemargin\paperwidth + \advance\oddsidemargin by -\textwidth + \advance\oddsidemargin by -\@IEEEtrantmpdimenA + \advance\oddsidemargin by -1in\relax +\else + \if\@IEEEextractedtoken i\relax + \else + \@IEEEclspkgerror{Unknown mode type `\@IEEEextractedtokenmacro' in \string\IEEEsetsidemargin\space (line \the\inputlineno).\MessageBreak + Defaulting to `i'}% + {Valid modes for \string\IEEEsetsidemargin\space are: i, o, c and a.}% + \fi + \oddsidemargin\@IEEEtrantmpdimenA + \advance\oddsidemargin by -1in\relax +\fi\fi\fi +% odd and even side margins both mean "inner" for single sided pages +\evensidemargin\oddsidemargin +% but are mirrors of each other when twosided is in effect +\if@twoside + \evensidemargin\paperwidth + \advance\evensidemargin by -\textwidth + \advance\evensidemargin by -\oddsidemargin + % have to compensate for both the builtin 1in LaTex offset + % and the fact we already subtracted this offset from \oddsidemargin + \advance\evensidemargin -2in\relax +\fi} + + + +% usage: \IEEEsettextheight[sample text]{top text margin}{bottom text margin} +% Sets \textheight based on the specified top margin and bottom margin. +% Takes into consideration \paperheight, \topskip, and (by default) the +% the actual height and depth of the \IEEEdefaultsampletext text. +\def\IEEEsettextheight{\@ifnextchar [{\@IEEEsettextheight}{\@IEEEsettextheight[\IEEEdefaultsampletext]}} +\def\@IEEEsettextheight[#1]#2#3{\textheight\paperheight\relax + \@IEEEtrantmpdimenA #2\relax + \advance \textheight by -\@IEEEtrantmpdimenA% subtract top margin + \@IEEEtrantmpdimenA #3\relax + \advance \textheight by -\@IEEEtrantmpdimenA% subtract bottom margin + \advance \textheight by \topskip% add \topskip + % subtract off everything above the top, and below the bottom, baselines + \settoheight{\@IEEEtrantmpdimenA}{\begingroup #1\relax\relax\relax\endgroup}\relax + \advance \textheight by -\@IEEEtrantmpdimenA + \settodepth{\@IEEEtrantmpdimenA}{\begingroup #1\relax\relax\relax\endgroup}\relax + \advance \textheight by -\@IEEEtrantmpdimenA} + + + +\newdimen\IEEEquantizedlength +\IEEEquantizedlength 0sp\relax +\newdimen\IEEEquantizedlengthdiff +\IEEEquantizedlengthdiff 0sp\relax +\def\IEEEquantizedlengthint{0} + +% usage: \IEEEquantizelength{mode: d, c, i}{base unit}{length} +% Sets the length \IEEEquantizedlength to be an integer multiple of the given +% (nonzero) base unit such that \IEEEquantizedlength approximates the given +% length. +% \IEEEquantizedlengthdiff is a length equal to the difference between the +% \IEEEquantizedlength and the given length. +% \IEEEquantizedlengthint is a macro containing the integer number of base units +% in \IEEEquantizedlength. +% i.e., \IEEEquantizedlength = \IEEEquantizedlengthint * base unit +% The mode determines how \IEEEquantizedlength is quantized: +% d = always decrease (always round down \IEEEquantizeint) +% c = use the closest match +% i = always increase (always round up \IEEEquantizeint) +% In anycase, if the given length is already quantized, +% \IEEEquantizedlengthdiff will be set to zero. +\def\IEEEquantizelength#1#2#3{\begingroup +% work in isolation so as not to externally disturb the \@IEEEtrantmp +% variables +% load the argument values indirectly via \IEEEquantizedlengthdiff +% in case the user refers to our \@IEEEtrantmpdimenX, \IEEEquantizedlength, +% etc. in the arguments. we also will work with these as counters, +% i.e., in sp units +% A has the base unit +\IEEEquantizedlengthdiff #2\relax\relax\relax\relax +\@IEEEtrantmpcountA\IEEEquantizedlengthdiff +% B has the input length +\IEEEquantizedlengthdiff #3\relax\relax\relax\relax +\@IEEEtrantmpcountB\IEEEquantizedlengthdiff +\@IEEEtrantmpdimenA\the\@IEEEtrantmpcountA sp\relax +\@IEEEtrantmpdimenB\the\@IEEEtrantmpcountB sp\relax +% \@IEEEtrantmpcountC will have the quantized int +% \IEEEquantizedlength will have the quantized length +% \@IEEEtrantmpdimenC will have the quantized diff +% initialize them to zero as this is what will be +% exported if an error occurs +\@IEEEtrantmpcountC 0\relax +\IEEEquantizedlength 0sp\relax +\@IEEEtrantmpdimenC 0sp\relax +% extract mode +\@IEEEextracttoken{#1}\relax +% check for mode errors +\ifx\@IEEEextractedtokenmacro\@empty + \@IEEEclspkgerror{Empty mode type in \string\IEEEquantizelength\space (line \the\inputlineno).\MessageBreak + Defaulting to `d'}{Valid modes for \string\IEEEquantizelength\space are: d, c and i.}\relax + \let\@IEEEextractedtoken=d\relax + \def\@IEEEextractedtokenmacro{d}\relax +\else + \ifx\@IEEEextractedtokensdiscarded\@empty\else + \typeout{** WARNING: \string\IEEEquantizelength\space mode specifiers after the first in `\@IEEEextracttokenarg' ignored (line \the\inputlineno).}\relax + \fi +\fi +% check for base unit is zero error +\ifnum\@IEEEtrantmpcountA=0\relax +\@IEEEclspkgerror{Base unit is zero in \string\IEEEquantizelength\space (line \the\inputlineno).\MessageBreak + \string\IEEEquantizedlength\space and \string\IEEEquantizedlengthdiff\space are set to zero}{Division by zero is not allowed.}\relax +\else% base unit is nonzero + % \@IEEEtrantmpcountC carries the number of integer units + % in the quantized length (integer length \ base) + \@IEEEtrantmpcountC\@IEEEtrantmpcountB\relax + \divide\@IEEEtrantmpcountC by \@IEEEtrantmpcountA\relax + % \IEEEquantizedlength has the (rounded down) quantized length + % = base * int + \IEEEquantizedlength\@IEEEtrantmpdimenA\relax + \multiply\IEEEquantizedlength by \@IEEEtrantmpcountC\relax + % \@IEEEtrantmpdimenC has the difference + % = quantized length - length + \@IEEEtrantmpdimenC\IEEEquantizedlength\relax + \advance\@IEEEtrantmpdimenC by -\@IEEEtrantmpdimenB\relax + % trap special case of length being already quantized + % to avoid a roundup under i option + \ifdim\@IEEEtrantmpdimenC=0sp\relax + \else % length not is already quantized + % set dimenA to carry the upper quantized (absolute value) difference: + % quantizedlength + base - length + \advance\@IEEEtrantmpdimenA by \IEEEquantizedlength\relax + \advance\@IEEEtrantmpdimenA by -\@IEEEtrantmpdimenB\relax + % set dimenB to carry the lower quantized (absolute value) difference: + % length - quantizedlength + \advance\@IEEEtrantmpdimenB by -\IEEEquantizedlength\relax + % handle each mode + \if\@IEEEextractedtoken c\relax + % compare upper and lower amounts, select upper if lower > upper + \ifdim\@IEEEtrantmpdimenB>\@IEEEtrantmpdimenA\relax + % use upper + \advance\IEEEquantizedlength by \the\@IEEEtrantmpcountA sp\relax + \advance\@IEEEtrantmpcountC by 1\relax + \@IEEEtrantmpdimenC\@IEEEtrantmpdimenA + \else% <=. uselower + % no need to do anything for lower, use output values already setup + \fi + \else% not mode c + \if\@IEEEextractedtoken i\relax + % always round up under i mode + \advance\IEEEquantizedlength by \the\@IEEEtrantmpcountA sp\relax + \advance\@IEEEtrantmpcountC by 1\relax + \@IEEEtrantmpdimenC\@IEEEtrantmpdimenA + \else + \if\@IEEEextractedtoken d\relax + \else + \@IEEEclspkgerror{Unknown mode type `\@IEEEextractedtokenmacro' in \string\IEEEquantizelength\space (line \the\inputlineno).\MessageBreak + Defaulting to `d'}% + {Valid modes for \string\IEEEquantizelength\space are: d, c, and i.}\relax + \fi % if d + % no need to do anything for d, use output values already setup + \fi\fi % if i, c + \fi % if length is already quantized +\fi% if base unit is zero +% globally assign the results to macros we use here to escape the enclosing +% group without needing to call \global on any of the \@IEEEtrantmp variables. +% \@IEEEtrantmpcountC has the quantized int +% \IEEEquantizedlength has the quantized length +% \@IEEEtrantmpdimenC has the quantized diff +\xdef\@IEEEquantizedlengthintmacro{\the\@IEEEtrantmpcountC}\relax +\@IEEEtrantmpcountC\IEEEquantizedlength\relax +\xdef\@IEEEquantizedlengthmacro{\the\@IEEEtrantmpcountC}\relax +\@IEEEtrantmpcountC\@IEEEtrantmpdimenC\relax +\xdef\@IEEEquantizedlengthdiffmacro{\the\@IEEEtrantmpcountC}\relax +\endgroup +% locally assign the outputs here from the macros +\expandafter\IEEEquantizedlength\@IEEEquantizedlengthmacro sp\relax +\expandafter\IEEEquantizedlengthdiff\@IEEEquantizedlengthdiffmacro sp\relax +\edef\IEEEquantizedlengthint{\@IEEEquantizedlengthintmacro}\relax} + + + +\newdimen\IEEEquantizedtextheightdiff +\IEEEquantizedtextheightdiff 0sp\relax + +% usage: \IEEEquantizetextheight[base unit]{mode: d, c, i} +% Sets \textheight to be an integer multiple of the current \baselineskip +% (or the optionally specified base unit) plus the first (\topskip) line. +% \IEEEquantizedtextheightdiff is a length equal to the difference between +% the new quantized and original \textheight. +% \IEEEquantizedtextheightlpc is a macro containing the integer number of +% lines per column under the quantized \textheight. i.e., +% \textheight = \IEEEquantizedtextheightlpc * \baselineskip + \topskip +% The mode determines how \textheight is quantized: +% d = always decrease (always round down the number of lines per column) +% c = use the closest match +% i = always increase (always round up the number of lines per column) +% In anycase, if \textheight is already quantized, it will remain unchanged, +% and \IEEEquantizedtextheightdiff will be set to zero. +% Depends on: \IEEEquantizelength +\def\IEEEquantizetextheight{\@ifnextchar [{\@IEEEquantizetextheight}{\@IEEEquantizetextheight[\baselineskip]}} +\def\@IEEEquantizetextheight[#1]#2{\begingroup +% use our \IEEEquantizedtextheightdiff as a scratch pad +% we need to subtract off \topskip before quantization +\IEEEquantizedtextheightdiff\textheight +\advance\IEEEquantizedtextheightdiff by -\topskip\relax +\IEEEquantizelength{#2}{#1}{\IEEEquantizedtextheightdiff} +% add back \topskip line +\advance\IEEEquantizedlength by \topskip +\@IEEEtrantmpcountC\IEEEquantizedlengthint\relax +\advance\@IEEEtrantmpcountC by 1\relax +% globally assign the results to macros we use here to escape the enclosing +% group without needing to call \global on any of the \@IEEEtrantmp variables. +\xdef\@IEEEquantizedtextheightlpcmacro{\the\@IEEEtrantmpcountC}\relax +\@IEEEtrantmpcountC\IEEEquantizedlength\relax +\xdef\@IEEEquantizedtextheightmacro{\the\@IEEEtrantmpcountC}\relax +\@IEEEtrantmpcountC\IEEEquantizedlengthdiff\relax +\xdef\@IEEEquantizedtextheightdiffmacro{\the\@IEEEtrantmpcountC}\relax +\endgroup +% locally assign the outputs here from the macros +\textheight\@IEEEquantizedtextheightmacro sp\relax +\IEEEquantizedtextheightdiff\@IEEEquantizedtextheightdiffmacro sp\relax +\edef\IEEEquantizedtextheightlpc{\@IEEEquantizedtextheightlpcmacro}} + + + +% usage: \IEEEsettopmargin[sample text]{mode: t, b, c, a, q}{margin/offset} +% Sets \topmargin based on the specified vertical margin. +% Takes into consideration the base 1in offset, \headheight, \headsep, +% \topskip, and (by default) the the actual height (or, for the bottom, depth) +% of the \IEEEdefaultsampletext text. +% The available modes are: +% t = top margin +% b = bottom margin +% c = vertically centered, with the given offset +% a = adjust the vertical margins using the given offset +% q = adjust the margins using \IEEEquantizedtextheightdiff and the given offset +% For the offsets, positive values increase the top margin. +% \headheight, \headsep, \topskip and \textheight should be set properly for the +% given margins before calling this function. +\def\IEEEsettopmargin{\@ifnextchar [{\@IEEEsettopmargin}{\@IEEEsettopmargin[\IEEEdefaultsampletext]}} +\def\@IEEEsettopmargin[#1]#2#3{\@IEEEtrantmpdimenA #3\relax +\@IEEEextracttoken{#2}\relax +% check for mode errors +\ifx\@IEEEextractedtokenmacro\@empty + \@IEEEclspkgerror{Empty mode type in \string\IEEEsettopmargin\space (line \the\inputlineno).\MessageBreak + Defaulting to `t'}{Valid modes for \string\IEEEsettopmargin\space are: t, b, c, a and q.}\relax + \let\@IEEEextractedtoken=t\relax + \def\@IEEEextractedtokenmacro{t}\relax +\else + \ifx\@IEEEextractedtokensdiscarded\@empty\else + \typeout{** WARNING: \string\IEEEsettopmargin\space mode specifiers after the first in `\@IEEEextracttokenarg' ignored (line \the\inputlineno).}\relax + \fi +\fi +% handle each mode +\if\@IEEEextractedtoken a\relax + \advance\topmargin by \@IEEEtrantmpdimenA\relax +\else +\if\@IEEEextractedtoken q\relax + % we need to adjust by half the \IEEEquantizedtextheightdiff value + \@IEEEtrantmpdimenB\IEEEquantizedtextheightdiff\relax + \divide\@IEEEtrantmpdimenB by 2\relax + % a positive \IEEEquantizedtextheightdiff means we need to reduce \topmargin + % because \textheight has been lenghtened + \advance\topmargin by -\@IEEEtrantmpdimenB\relax + \advance\topmargin by \@IEEEtrantmpdimenA\relax +\else +\if\@IEEEextractedtoken c\relax + \topmargin\paperheight + \advance\topmargin by -\textheight + % \textheight includes \topskip, but we should not count topskip whitespace here, backout + \advance \topmargin by \topskip + \settoheight{\@IEEEtrantmpdimenB}{\begingroup #1\relax\relax\relax\endgroup}\relax + \advance\topmargin by -\@IEEEtrantmpdimenB\relax + \settodepth{\@IEEEtrantmpdimenB}{\begingroup #1\relax\relax\relax\endgroup}\relax + \advance\topmargin by -\@IEEEtrantmpdimenB\relax + \divide\topmargin by 2\relax + \advance\topmargin by \@IEEEtrantmpdimenA\relax +\else +\if\@IEEEextractedtoken b\relax + \topmargin\paperheight + \advance\topmargin by -\textheight + % \textheight includes \topskip, but we should not count topskip whitespace here, backout + \advance \topmargin by \topskip + \settodepth{\@IEEEtrantmpdimenB}{\begingroup #1\relax\relax\relax\endgroup}\relax + \advance\topmargin by -\@IEEEtrantmpdimenB\relax + \advance\topmargin by -\@IEEEtrantmpdimenA\relax +\else + \if\@IEEEextractedtoken t\relax + \else + \@IEEEclspkgerror{Unknown mode type `\@IEEEextractedtokenmacro' in \string\IEEEsettopmargin\space (line \the\inputlineno).\MessageBreak + Defaulting to `t'}% + {Valid modes for \string\IEEEsettopmargin\space are: t, b, c, a and q.}\relax + \fi + \topmargin\@IEEEtrantmpdimenA\relax + \settoheight{\@IEEEtrantmpdimenB}{\begingroup #1\relax\relax\relax\endgroup}\relax + \advance\topmargin by \@IEEEtrantmpdimenB\relax +\fi\fi % if t, b, c +% convert desired top margin into actual \topmargin +% this is not done for the q or a modes because they are only adjustments +\advance \topmargin by -\topskip +\advance \topmargin by -1in +\advance \topmargin by -\headheight +\advance \topmargin by -\headsep +\fi\fi % if q, a +} + + + +% usage: \IEEEsetheadermargin[header sample][text sample]{mode: t, b, c, a}{margin/offset} +% Differentially adjusts \topmargin and \headsep (such that their sum is unchanged) +% based on the specified header margin. +% Takes into consideration the base 1in offset, \headheight, \topskip, and (by default) +% the actual height (or depth) of the \IEEEdefaultheadersampletext and +% \IEEEdefaultsampletext text. +% The available modes are: +% t = top margin (top of the header text to the top of the page) +% b = bottom margin (bottom of the header text to the top of the main text) +% c = vertically centered between the main text and the top of the page, +% with the given offset +% a = adjust the vertical position using the given offset +% For the offsets, positive values move the header downward. +% \headheight, \headsep, \topskip and \topmargin should be set properly before +% calling this function. +\def\IEEEsetheadermargin{\@ifnextchar [{\@IEEEsetheadermargin}{\@IEEEsetheadermargin[\IEEEdefaultheadersampletext]}} +\def\@IEEEsetheadermargin[#1]{\@ifnextchar [{\@@IEEEsetheadermargin[#1]}{\@@IEEEsetheadermargin[#1][\IEEEdefaultsampletext]}} +\def\@@IEEEsetheadermargin[#1][#2]#3#4{\@IEEEtrantmpdimenA #4\relax +\@IEEEextracttoken{#3}\relax +% check for mode errors +\ifx\@IEEEextractedtokenmacro\@empty + \@IEEEclspkgerror{Empty mode type in \string\IEEEsetheadermargin\space (line \the\inputlineno).\MessageBreak + Defaulting to `t'}{Valid modes for \string\IEEEsetheadermargin\space are: t, b, c, and a.}\relax + \let\@IEEEextractedtoken=t\relax + \def\@IEEEextractedtokenmacro{t}\relax +\else + \ifx\@IEEEextractedtokensdiscarded\@empty\else + \typeout{** WARNING: \string\IEEEsetheadermargin\space mode specifiers after the first in `\@IEEEextracttokenarg' ignored (line \the\inputlineno).}\relax + \fi +\fi +% handle each mode +\if\@IEEEextractedtoken a\relax + % No need to do anything here and can pass through the adjustment + % value as is. The end adjustment of \topmargin and \headsep will + % do all that is needed +\else +\if\@IEEEextractedtoken c\relax + % get the bottom margin + \@IEEEtrantmpdimenB\headsep\relax + \settodepth{\@IEEEtrantmpdimenC}{\begingroup #1\relax\relax\relax\endgroup}\relax + \advance\@IEEEtrantmpdimenB by -\@IEEEtrantmpdimenC + \advance\@IEEEtrantmpdimenB by \topskip + \settoheight{\@IEEEtrantmpdimenC}{\begingroup #2\relax\relax\relax\endgroup}\relax + \advance\@IEEEtrantmpdimenB by -\@IEEEtrantmpdimenC + % at this point \@IEEEtrantmpdimenB has the actual header bottom margin + % subtract from it the top header margin + \advance\@IEEEtrantmpdimenB -1in\relax % take into consideration the system 1in offset of the top margin + \advance\@IEEEtrantmpdimenB by -\topmargin + \advance\@IEEEtrantmpdimenB by -\headheight + \settoheight{\@IEEEtrantmpdimenC}{\begingroup #1\relax\relax\relax\endgroup}\relax + \advance\@IEEEtrantmpdimenB by \@IEEEtrantmpdimenC + % at this point \@IEEEtrantmpdimenB has the difference between the bottom and top margins + % we need to adjust by half this amount to center the header + \divide\@IEEEtrantmpdimenB by 2\relax + % and add to offset + \advance\@IEEEtrantmpdimenA by \@IEEEtrantmpdimenB +\else +\if\@IEEEextractedtoken b\relax + \@IEEEtrantmpdimenB\headsep\relax + \settodepth{\@IEEEtrantmpdimenC}{\begingroup #1\relax\relax\relax\endgroup}\relax + \advance\@IEEEtrantmpdimenB by -\@IEEEtrantmpdimenC + \advance\@IEEEtrantmpdimenB by \topskip + \settoheight{\@IEEEtrantmpdimenC}{\begingroup #2\relax\relax\relax\endgroup}\relax + \advance\@IEEEtrantmpdimenB by -\@IEEEtrantmpdimenC + % at this point \@IEEEtrantmpdimenB has the actual header bottom margin + % get the difference between the actual and the desired + \advance\@IEEEtrantmpdimenB by -\@IEEEtrantmpdimenA + \@IEEEtrantmpdimenA\@IEEEtrantmpdimenB +\else + \if\@IEEEextractedtoken t\relax + \else + \@IEEEclspkgerror{Unknown mode type `\@IEEEextractedtokenmacro' in \string\IEEEsetheadermargin\space (line \the\inputlineno).\MessageBreak + Defaulting to `t'}% + {Valid modes for \string\IEEEsetheadermargin\space are: t, b, c and a.}\relax + \fi + \@IEEEtrantmpdimenB 1in\relax % take into consideration the system 1in offset of the top margin + \advance\@IEEEtrantmpdimenB by \topmargin + \advance\@IEEEtrantmpdimenB by \headheight + \settoheight{\@IEEEtrantmpdimenC}{\begingroup #1\relax\relax\relax\endgroup}\relax + \advance\@IEEEtrantmpdimenB by -\@IEEEtrantmpdimenC + % at this point \@IEEEtrantmpdimenB has the actual header top margin + % get the difference between the desired and the actual + \advance\@IEEEtrantmpdimenA by -\@IEEEtrantmpdimenB +\fi\fi % if t, b, c +\fi % if a +% advance \topmargin by the needed amount and reduce \headsep by the same +% so as not to disturb the location of the main text +\advance\topmargin by \@IEEEtrantmpdimenA\relax +\advance\headsep by -\@IEEEtrantmpdimenA\relax +} + + + +% usage: \IEEEsetfootermargin[footer sample][text sample]{mode: t, b, c, a}{margin/offset} +% Adjusts \footskip based on the specified footer margin. +% Takes into consideration the base 1in offset, \paperheight, \headheight, +% \headsep, \textheight and (by default) the actual height (or depth) of the +% \IEEEdefaultfootersampletext and \IEEEdefaultsampletext text. +% The available modes are: +% t = top margin (top of the footer text to the bottom of the main text) +% b = bottom margin (bottom of the footer text to the bottom of page) +% c = vertically centered between the main text and the bottom of the page, +% with the given offset +% a = adjust the vertical position using the given offset +% For the offsets, positive values move the footer downward. +% \headheight, \headsep, \topskip, \topmargin, and \textheight should be set +% properly before calling this function. +\def\IEEEsetfootermargin{\@ifnextchar [{\@IEEEsetfootermargin}{\@IEEEsetfootermargin[\IEEEdefaultfootersampletext]}} +\def\@IEEEsetfootermargin[#1]{\@ifnextchar [{\@@IEEEsetfootermargin[#1]}{\@@IEEEsetfootermargin[#1][\IEEEdefaultsampletext]}} +\def\@@IEEEsetfootermargin[#1][#2]#3#4{\@IEEEtrantmpdimenA #4\relax +\@IEEEextracttoken{#3}\relax +% check for mode errors +\ifx\@IEEEextractedtokenmacro\@empty + \@IEEEclspkgerror{Empty mode type in \string\IEEEsetfootermargin\space (line \the\inputlineno).\MessageBreak + Defaulting to `t'}{Valid modes for \string\IEEEsetfootermargin\space are: t, b, c, and a.}\relax + \let\@IEEEextractedtoken=t\relax + \def\@IEEEextractedtokenmacro{t}\relax +\else + \ifx\@IEEEextractedtokensdiscarded\@empty\else + \typeout{** WARNING: \string\IEEEsetfootermargin\space mode specifiers after the first in `\@IEEEextracttokenarg' ignored (line \the\inputlineno).}\relax + \fi +\fi +% handle each mode +\if\@IEEEextractedtoken a\relax + % No need to do anything here and can pass through the adjustment + % value as is. The end adjustment of \footskip will do all that + % is needed +\else +\if\@IEEEextractedtoken c\relax + % calculate the bottom margin + \@IEEEtrantmpdimenB 1in\relax % system 1in offset + \advance\@IEEEtrantmpdimenB\topmargin\relax + \advance\@IEEEtrantmpdimenB\headheight\relax + \advance\@IEEEtrantmpdimenB\headsep\relax + \advance\@IEEEtrantmpdimenB\textheight\relax + \advance\@IEEEtrantmpdimenB\footskip\relax + \settodepth{\@IEEEtrantmpdimenC}{\begingroup #1\relax\relax\relax\endgroup}\relax + \advance\@IEEEtrantmpdimenC by \@IEEEtrantmpdimenB + \@IEEEtrantmpdimenB\paperheight + \advance\@IEEEtrantmpdimenB by -\@IEEEtrantmpdimenC + % at this point \@IEEEtrantmpdimenB has the actual footer bottom margin + % now subtract off the footer top margin + \advance\@IEEEtrantmpdimenB -\footskip\relax + \settodepth{\@IEEEtrantmpdimenC}{\begingroup #2\relax\relax\relax\endgroup}\relax + \advance\@IEEEtrantmpdimenB by \@IEEEtrantmpdimenC + \settoheight{\@IEEEtrantmpdimenC}{\begingroup #1\relax\relax\relax\endgroup}\relax + \advance\@IEEEtrantmpdimenB by \@IEEEtrantmpdimenC + % at this point \@IEEEtrantmpdimenB has the difference between the bottom + % and top footer margins + % our adjustment must be half this value to center the footer + \divide\@IEEEtrantmpdimenB by 2\relax + % add to the offset + \advance\@IEEEtrantmpdimenA by \@IEEEtrantmpdimenB +\else +\if\@IEEEextractedtoken b\relax + % calculate the bottom margin + \@IEEEtrantmpdimenB 1in\relax % system 1in offset + \advance\@IEEEtrantmpdimenB\topmargin\relax + \advance\@IEEEtrantmpdimenB\headheight\relax + \advance\@IEEEtrantmpdimenB\headsep\relax + \advance\@IEEEtrantmpdimenB\textheight\relax + \advance\@IEEEtrantmpdimenB\footskip\relax + \settodepth{\@IEEEtrantmpdimenC}{\begingroup #1\relax\relax\relax\endgroup}\relax + \advance\@IEEEtrantmpdimenC by \@IEEEtrantmpdimenB + \@IEEEtrantmpdimenB\paperheight + \advance\@IEEEtrantmpdimenB by -\@IEEEtrantmpdimenC + % at this point \@IEEEtrantmpdimenB has the actual footer bottom margin + % get the difference between the actual and the desired + \advance\@IEEEtrantmpdimenB by -\@IEEEtrantmpdimenA + \@IEEEtrantmpdimenA\@IEEEtrantmpdimenB +\else + \if\@IEEEextractedtoken t\relax + \else + \@IEEEclspkgerror{Unknown mode type `\@IEEEextractedtokenmacro' in \string\IEEEsetfootermargin\space (line \the\inputlineno).\MessageBreak + Defaulting to `t'}% + {Valid modes for \string\IEEEsetfootermargin\space are: t, b, c and a.}\relax + \fi + \@IEEEtrantmpdimenB\footskip\relax + \settodepth{\@IEEEtrantmpdimenC}{\begingroup #2\relax\relax\relax\endgroup}\relax + \advance\@IEEEtrantmpdimenB by -\@IEEEtrantmpdimenC + \settoheight{\@IEEEtrantmpdimenC}{\begingroup #1\relax\relax\relax\endgroup}\relax + \advance\@IEEEtrantmpdimenB by -\@IEEEtrantmpdimenC + % at this point \@IEEEtrantmpdimenB has the actual footer top margin + % get the difference between the desired and the actual + \advance\@IEEEtrantmpdimenA by -\@IEEEtrantmpdimenB +\fi\fi % if t, b, c +\fi % if a +% advance \footskip by the needed amount +\advance\footskip by \@IEEEtrantmpdimenA\relax +} + +% -- End V1.8a page setup commands -- + + + + + +% V1.6 +% LaTeX is a little to quick to use hyphenations +% So, we increase the penalty for their use and raise +% the badness level that triggers an underfull hbox +% warning. The author may still have to tweak things, +% but the appearance will be much better "right out +% of the box" than that under V1.5 and prior. +% TeX default is 50 +\hyphenpenalty=750 +\ifCLASSOPTIONcompsoc +\hyphenpenalty 500 +\fi +% If we didn't adjust the interword spacing, 2200 might be better. +% The TeX default is 1000 +\hbadness=1350 +% The IEEE does not use extra spacing after punctuation +\frenchspacing + +% V1.7 increase this a tad to discourage equation breaks +\binoppenalty=1000 % default 700 +\relpenalty=800 % default 500 + +% v1.8a increase these to discourage widows and orphans +\clubpenalty=1000 % default 150 +\widowpenalty=1000 % default 150 +\displaywidowpenalty=1000 % default 50 + + +% margin note stuff +\marginparsep 10pt +\marginparwidth 20pt +\marginparpush 25pt + + +% if things get too close, go ahead and let them touch +\lineskip 0pt +\normallineskip 0pt +\lineskiplimit 0pt +\normallineskiplimit 0pt + +% The distance from the lower edge of the text body to the +% footline +\footskip 0.4in + +% normally zero, should be relative to font height. +% put in a little rubber to help stop some bad breaks (underfull vboxes) +\parskip 0ex plus 0.2ex minus 0.1ex + +\parindent 1.0em +\ifCLASSOPTIONcompsoc + \parindent 1.5em +\fi + +\headheight 12pt +\headsep 18pt +% use the normal font baselineskip +% so that \topskip is unaffected by changes in \baselinestretch +\topskip=\@IEEEnormalsizeunitybaselineskip + + +% V1.8 \maxdepth defaults to 4pt, but should be font size dependent +\maxdepth=0.5\@IEEEnormalsizeunitybaselineskip +\textheight 58pc % 9.63in, 696pt + +% set the default top margin to 58pt +% which results in a \topmargin of -49.59pt for 10pt documents +\IEEEsettopmargin{t}{58pt} +% tweak textheight to a perfect integer number of lines/column. +% standard is: 9pt/63 lpc; 10pt/58 lpc; 11pt/52 lpc; 12pt/50 lpc +\IEEEquantizetextheight{c} +% tweak top margin so that the error is shared equally at the top and bottom +\IEEEsettopmargin{q}{0sp} + + +\columnsep 1pc +\textwidth 43pc % 2 x 21pc + 1pc = 43pc + +% set the default side margins to center the text +\IEEEsetsidemargin{c}{0pt} + + +% adjust margins for default conference mode +\ifCLASSOPTIONconference + \textheight 9.25in % The standard for conferences (668.4975pt) + \IEEEsettopmargin{t}{0.75in} + % tweak textheight to a perfect integer number of lines/page. + % standard is: 9pt/61 lpc; 10pt/56 lpc; 11pt/50 lpc; 12pt/48 lpc + \IEEEquantizetextheight{c} + % tweak top margin so that the error is shared equally at the top and bottom + \IEEEsettopmargin{q}{0sp} +\fi + + +% compsoc text sizes, margins and spacings +\ifCLASSOPTIONcompsoc + \columnsep 12bp + % CS specs for \textwdith are 6.875in + % \textwidth 6.875in + % however, measurements from proofs show they are using 3.5in columns + \textwidth 7in + \advance\textwidth by \columnsep + % set the side margins to center the text + \IEEEsetsidemargin{c}{0pt} + % top/bottom margins to center + % could just set \textheight to 9.75in for all the different paper sizes + % and then quantize, but we'll do it the long way here to allow for easy + % future per-paper size adjustments + \IEEEsettextheight{0.625in}{0.625in}% 11in - 2 * 0.625in = 9.75in is the standard text height for compsoc journals + \IEEEsettopmargin{t}{0.625in} + \if@IEEEusingcspaper + \IEEEsettextheight{0.5in}{0.5in}% 10.75in - 2 * 0.5in = 9.75in + \IEEEsettopmargin{t}{0.5in} + \fi + \if@IEEEusingAfourpaper + \IEEEsettextheight{24.675mm}{24.675mm}% 297mm - 2 * 24.675mm = 247.650mm (9.75in) + \IEEEsettopmargin{t}{24.675mm} + \fi + % tweak textheight to a perfect integer number of lines/page. + % standard is: 9pt/65 lpc; 10pt/61 lpc; 11pt/53 lpc; 12pt/49 lpc + \IEEEquantizetextheight{c} + % tweak top margin so that the error is shared equally at the top and bottom + \IEEEsettopmargin{q}{0sp} + +% compsoc conference + \ifCLASSOPTIONconference + % compsoc conference use a larger value for columnsep + \columnsep 0.25in + \IEEEsettextwidth{0.75in}{0.75in} + % set the side margins to center the text (0.75in for letterpaper) + \IEEEsetsidemargin{c}{0pt} + % compsoc conferences want 1in top and bottom margin + \IEEEsettextheight{1in}{1in} + \IEEEsettopmargin{t}{1in} + % tweak textheight to a perfect integer number of lines/page. + % standard is: 9pt/58 lpc; 10pt/53 lpc; 11pt/48 lpc; 12pt/46 lpc + \IEEEquantizetextheight{c} + % tweak top margin so that the error is shared equally at the top and bottom + \IEEEsettopmargin{q}{0sp} + \fi +\fi + + + +% draft mode settings override that of all other modes +% provides a nice 1in margin all around the paper and extra +% space between the lines for editor's comments +\ifCLASSOPTIONdraftcls + % we want 1in side margins regardless of paper type + \IEEEsettextwidth{1in}{1in} + \IEEEsetsidemargin{c}{0pt} + % want 1in top and bottom margins + \IEEEsettextheight{1in}{1in} + \IEEEsettopmargin{t}{1in} + % digitize textheight to be an integer number of lines. + % this may cause the top and bottom margins to be off a tad + \IEEEquantizetextheight{c} + % tweak top margin so that the error is shared equally at the top and bottom + \IEEEsettopmargin{q}{0sp} +\fi + + + +% process CLASSINPUT inner/outer margin +% if inner margin defined, but outer margin not, set outer to inner. +\ifx\CLASSINPUTinnersidemargin\@IEEEundefined +\else + \ifx\CLASSINPUToutersidemargin\@IEEEundefined + \edef\CLASSINPUToutersidemargin{\CLASSINPUTinnersidemargin} + \fi +\fi + +\ifx\CLASSINPUToutersidemargin\@IEEEundefined +\else + % if outer margin defined, but inner margin not, set inner to outer. + \ifx\CLASSINPUTinnersidemargin\@IEEEundefined + \edef\CLASSINPUTinnersidemargin{\CLASSINPUToutersidemargin} + \fi + \IEEEsettextwidth{\CLASSINPUTinnersidemargin}{\CLASSINPUToutersidemargin} + \IEEEsetsidemargin{i}{\CLASSINPUTinnersidemargin} + \typeout{** ATTENTION: Overriding inner side margin to \CLASSINPUTinnersidemargin\space and + outer side margin to \CLASSINPUToutersidemargin\space via \string\CLASSINPUT.} +\fi + + + +% process CLASSINPUT top/bottom text margin +% if toptext margin defined, but bottomtext margin not, set bottomtext to toptext margin +\ifx\CLASSINPUTtoptextmargin\@IEEEundefined +\else + \ifx\CLASSINPUTbottomtextmargin\@IEEEundefined + \edef\CLASSINPUTbottomtextmargin{\CLASSINPUTtoptextmargin} + \fi +\fi + +\ifx\CLASSINPUTbottomtextmargin\@IEEEundefined +\else + % if bottomtext margin defined, but toptext margin not, set toptext to bottomtext margin + \ifx\CLASSINPUTtoptextmargin\@IEEEundefined + \edef\CLASSINPUTtoptextmargin{\CLASSINPUTbottomtextmargin} + \fi + \IEEEsettextheight{\CLASSINPUTtoptextmargin}{\CLASSINPUTbottomtextmargin} + \IEEEsettopmargin{t}{\CLASSINPUTtoptextmargin} + \typeout{** ATTENTION: Overriding top text margin to \CLASSINPUTtoptextmargin\space and + bottom text margin to \CLASSINPUTbottomtextmargin\space via \string\CLASSINPUT.} +\fi + + + +% default to center header and footer text in the margins +\IEEEsetheadermargin{c}{0pt} +\IEEEsetfootermargin{c}{0pt} + +% adjust header and footer positions for compsoc journals +\ifCLASSOPTIONcompsoc + \ifCLASSOPTIONjournal + \IEEEsetheadermargin{b}{\@IEEEnormalsizeunitybaselineskip} + \IEEEsetfootermargin{t}{\@IEEEnormalsizeunitybaselineskip} + \fi +\fi + + +% V1.8a display lines per column info message on user's console +\def\IEEEdisplayinfolinespercolumn{\@IEEEtrantmpdimenA=\textheight +% topskip represents only one line even if > baselineskip +\advance\@IEEEtrantmpdimenA by -1\topskip +\@IEEEtrantmpcountA=\@IEEEtrantmpdimenA +\@IEEEtrantmpcountB=\@IEEEtrantmpdimenA +\divide\@IEEEtrantmpcountB by \baselineskip +% need to add one line to include topskip (first) line +\advance\@IEEEtrantmpcountB by 1 +% save lines per column value as text +\edef\@IEEEnumlinespercolumninfotxt{\the\@IEEEtrantmpcountB} +% backout topskip advance to allow direct \@IEEEtrantmpcountA comparison +\advance\@IEEEtrantmpcountB by -1 +% restore value as text height (without topskip) rather than just as number of lines +\multiply\@IEEEtrantmpcountB by \baselineskip +% is the column height an integer number of lines per column? +\ifnum\@IEEEtrantmpcountA=\@IEEEtrantmpcountB +\edef\@IEEEnumlinespercolumnexactinfotxt{exact} +\else +\@IEEEtrantmpdimenA\@IEEEtrantmpcountA sp\relax +\advance\@IEEEtrantmpdimenA by -\@IEEEtrantmpcountB sp\relax +\edef\@IEEEnumlinespercolumnexactinfotxt{approximate, difference = \the\@IEEEtrantmpdimenA} +\fi +\typeout{-- Lines per column: \@IEEEnumlinespercolumninfotxt\space (\@IEEEnumlinespercolumnexactinfotxt).}} +% delay execution till start of document to allow for user changes +\AtBeginDocument{\IEEEdisplayinfolinespercolumn} + + + +% LIST SPACING CONTROLS + +% Controls the amount of EXTRA spacing +% above and below \trivlist +% Both \list and IED lists override this. +% However, \trivlist will use this as will most +% things built from \trivlist like the \center +% environment. +\topsep 0.5\baselineskip + +% Controls the additional spacing around lists preceded +% or followed by blank lines. the IEEE does not increase +% spacing before or after paragraphs so it is set to zero. +% \z@ is the same as zero, but faster. +\partopsep \z@ + +% Controls the spacing between paragraphs in lists. +% The IEEE does not increase spacing before or after paragraphs +% so this is also zero. +% With IEEEtran.cls, global changes to +% this value DO affect lists (but not IED lists). +\parsep \z@ + +% Controls the extra spacing between list items. +% The IEEE does not put extra spacing between items. +% With IEEEtran.cls, global changes to this value DO affect +% lists (but not IED lists). +\itemsep \z@ + +% \itemindent is the amount to indent the FIRST line of a list +% item. It is auto set to zero within the \list environment. To alter +% it, you have to do so when you call the \list. +% However, the IEEE uses this for the theorem environment +% There is an alternative value for this near \leftmargini below +\itemindent -1em + +% \leftmargin, the spacing from the left margin of the main text to +% the left of the main body of a list item is set by \list. +% Hence this statement does nothing for lists. +% But, quote and verse do use it for indention. +\leftmargin 2em + +% we retain this stuff from the older IEEEtran.cls so that \list +% will work the same way as before. However, itemize, enumerate and +% description (IED) could care less about what these are as they +% all are overridden. +\leftmargini 2em +%\itemindent 2em % Alternative values: sometimes used. +%\leftmargini 0em +\leftmarginii 1em +\leftmarginiii 1.5em +\leftmarginiv 1.5em +\leftmarginv 1.0em +\leftmarginvi 1.0em +\labelsep 0.5em +\labelwidth \z@ + + +% The old IEEEtran.cls behavior of \list is retained. +% However, the new V1.3 IED list environments override all the +% @list stuff (\@listX is called within \list for the +% appropriate level just before the user's list_decl is called). +% \topsep is now 2pt as the IEEE puts a little extra space around +% lists - used by those non-IED macros that depend on \list. +% Note that \parsep and \itemsep are not redefined as in +% the sizexx.clo \@listX (which article.cls uses) so global changes +% of these values DO affect \list +% +\def\@listi{\leftmargin\leftmargini \topsep 2pt plus 1pt minus 1pt} +\let\@listI\@listi +\def\@listii{\leftmargin\leftmarginii\labelwidth\leftmarginii% + \advance\labelwidth-\labelsep \topsep 2pt} +\def\@listiii{\leftmargin\leftmarginiii\labelwidth\leftmarginiii% + \advance\labelwidth-\labelsep \topsep 2pt} +\def\@listiv{\leftmargin\leftmarginiv\labelwidth\leftmarginiv% + \advance\labelwidth-\labelsep \topsep 2pt} +\def\@listv{\leftmargin\leftmarginv\labelwidth\leftmarginv% + \advance\labelwidth-\labelsep \topsep 2pt} +\def\@listvi{\leftmargin\leftmarginvi\labelwidth\leftmarginvi% + \advance\labelwidth-\labelsep \topsep 2pt} + + +% The IEEE uses 5) not 5. +\def\labelenumi{\theenumi)} \def\theenumi{\arabic{enumi}} + +% The IEEE uses a) not (a) +\def\labelenumii{\theenumii)} \def\theenumii{\alph{enumii}} + +% The IEEE uses iii) not iii. +\def\labelenumiii{\theenumiii)} \def\theenumiii{\roman{enumiii}} + +% The IEEE uses A) not A. +\def\labelenumiv{\theenumiv)} \def\theenumiv{\Alph{enumiv}} + +% exactly the same as in article.cls +\def\p@enumii{\theenumi} +\def\p@enumiii{\theenumi(\theenumii)} +\def\p@enumiv{\p@enumiii\theenumiii} + +% itemized list label styles +\def\labelitemi{$\scriptstyle\bullet$} +\def\labelitemii{\textbf{--}} +\def\labelitemiii{$\ast$} +\def\labelitemiv{$\cdot$} + + + +% **** V1.3 ENHANCEMENTS **** +% Itemize, Enumerate and Description (IED) List Controls +% *************************** +% +% +% The IEEE seems to use at least two different values by +% which ITEMIZED list labels are indented to the right +% For The Journal of Lightwave Technology (JLT) and The Journal +% on Selected Areas in Communications (JSAC), they tend to use +% an indention equal to \parindent. For Transactions on Communications +% they tend to indent ITEMIZED lists a little more--- 1.3\parindent. +% We'll provide both values here for you so that you can choose +% which one you like in your document using a command such as: +% setlength{\IEEEilabelindent}{\IEEEilabelindentB} +\newdimen\IEEEilabelindentA +\IEEEilabelindentA \parindent + +\newdimen\IEEEilabelindentB +\IEEEilabelindentB 1.3\parindent +% However, we'll default to using \parindent +% which makes more sense to me +\newdimen\IEEEilabelindent +\IEEEilabelindent \IEEEilabelindentA + + +% This controls the default amount the enumerated list labels +% are indented to the right. +% Normally, this is the same as the paragraph indention +\newdimen\IEEEelabelindent +\IEEEelabelindent \parindent + +% This controls the default amount the description list labels +% are indented to the right. +% Normally, this is the same as the paragraph indention +\newdimen\IEEEdlabelindent +\IEEEdlabelindent \parindent + +% This is the value actually used within the IED lists. +% The IED environments automatically set its value to +% one of the three values above, so global changes do +% not have any effect +\newdimen\IEEElabelindent +\IEEElabelindent \parindent + +% The actual amount labels will be indented is +% \IEEElabelindent multiplied by the factor below +% corresponding to the level of nesting depth +% This provides a means by which the user can +% alter the effective \IEEElabelindent for deeper +% levels +% There may not be such a thing as correct "standard IEEE" +% values. What the IEEE actually does may depend on the specific +% circumstances. +% The first list level almost always has full indention. +% The second levels I've seen have only 75% of the normal indentation +% Three level or greater nestings are very rare. I am guessing +% that they don't use any indentation. +\def\IEEElabelindentfactori{1.0} % almost always one +\def\IEEElabelindentfactorii{0.75} % 0.0 or 1.0 may be used in some cases +\def\IEEElabelindentfactoriii{0.0} % 0.75? 0.5? 0.0? +\def\IEEElabelindentfactoriv{0.0} +\def\IEEElabelindentfactorv{0.0} +\def\IEEElabelindentfactorvi{0.0} + +% value actually used within IED lists, it is auto +% set to one of the 6 values above +% global changes here have no effect +\def\IEEElabelindentfactor{1.0} + +% This controls the default spacing between the end of the IED +% list labels and the list text, when normal text is used for +% the labels. +% compsoc uses a larger value here, but we'll set that later +% in the class so that this code block area can be extracted +% as-is for IEEEtrantools.sty +\newdimen\IEEEiednormlabelsep +\IEEEiednormlabelsep 0.6em + +% This controls the default spacing between the end of the IED +% list labels and the list text, when math symbols are used for +% the labels (nomenclature lists). The IEEE usually increases the +% spacing in these cases +\newdimen\IEEEiedmathlabelsep +\IEEEiedmathlabelsep 1.2em + +% This controls the extra vertical separation put above and +% below each IED list. the IEEE usually puts a little extra spacing +% around each list. However, this spacing is barely noticeable. +% compsoc uses a larger value here, but we'll set that later +% in the class so that this code block area can be extracted +% as-is for IEEEtrantools.sty +\newskip\IEEEiedtopsep +\IEEEiedtopsep 2pt plus 1pt minus 1pt + + +% This command is executed within each IED list environment +% at the beginning of the list. You can use this to set the +% parameters for some/all your IED list(s) without disturbing +% global parameters that affect things other than lists. +% i.e., renewcommand{\IEEEiedlistdecl}{\setlength{\labelsep}{5em}} +% will alter the \labelsep for the next list(s) until +% \IEEEiedlistdecl is redefined. +\def\IEEEiedlistdecl{\relax} + +% This command provides an easy way to set \leftmargin based +% on the \labelwidth, \labelsep and the argument \IEEElabelindent +% Usage: \IEEEcalcleftmargin{width-to-indent-the-label} +% output is in the \leftmargin variable, i.e., effectively: +% \leftmargin = argument + \labelwidth + \labelsep +% Note controlled spacing here, shield end of lines with % +\def\IEEEcalcleftmargin#1{\setlength{\leftmargin}{#1}% +\addtolength{\leftmargin}{\labelwidth}% +\addtolength{\leftmargin}{\labelsep}} + +% This command provides an easy way to set \labelwidth to the +% width of the given text. It is the same as +% \settowidth{\labelwidth}{label-text} +% and useful as a shorter alternative. +% Typically used to set \labelwidth to be the width +% of the longest label in the list +\def\IEEEsetlabelwidth#1{\settowidth{\labelwidth}{#1}} + +% When this command is executed, IED lists will use the +% IEEEiedmathlabelsep label separation rather than the normal +% spacing. To have an effect, this command must be executed via +% the \IEEEiedlistdecl or within the option of the IED list +% environments. +\def\IEEEusemathlabelsep{\setlength{\labelsep}{\IEEEiedmathlabelsep}} + +% A flag which controls whether the IED lists automatically +% calculate \leftmargin from \IEEElabelindent, \labelwidth and \labelsep +% Useful if you want to specify your own \leftmargin +% This flag must be set (\IEEEnocalcleftmargintrue or \IEEEnocalcleftmarginfalse) +% via the \IEEEiedlistdecl or within the option of the IED list +% environments to have an effect. +\newif\ifIEEEnocalcleftmargin +\IEEEnocalcleftmarginfalse + +% A flag which controls whether \IEEElabelindent is multiplied by +% the \IEEElabelindentfactor for each list level. +% This flag must be set via the \IEEEiedlistdecl or within the option +% of the IED list environments to have an effect. +\newif\ifIEEEnolabelindentfactor +\IEEEnolabelindentfactorfalse + + +% internal variable to indicate type of IED label +% justification +% 0 - left; 1 - center; 2 - right +\def\@IEEEiedjustify{0} + + +% commands to allow the user to control IED +% label justifications. Use these commands within +% the IED environment option or in the \IEEEiedlistdecl +% Note that changing the normal list justifications +% is nonstandard and the IEEE may not like it if you do so! +% I include these commands as they may be helpful to +% those who are using these enhanced list controls for +% other non-IEEE related LaTeX work. +% itemize and enumerate automatically default to right +% justification, description defaults to left. +\def\IEEEiedlabeljustifyl{\def\@IEEEiedjustify{0}}%left +\def\IEEEiedlabeljustifyc{\def\@IEEEiedjustify{1}}%center +\def\IEEEiedlabeljustifyr{\def\@IEEEiedjustify{2}}%right + + + + +% commands to save to and restore from the list parameter copies +% this allows us to set all the list parameters within +% the list_decl and prevent \list (and its \@list) +% from overriding any of our parameters +% V1.6 use \edefs instead of dimen's to conserve dimen registers +% Note controlled spacing here, shield end of lines with % +\def\@IEEEsavelistparams{\edef\@IEEEiedtopsep{\the\topsep}% +\edef\@IEEEiedlabelwidth{\the\labelwidth}% +\edef\@IEEEiedlabelsep{\the\labelsep}% +\edef\@IEEEiedleftmargin{\the\leftmargin}% +\edef\@IEEEiedpartopsep{\the\partopsep}% +\edef\@IEEEiedparsep{\the\parsep}% +\edef\@IEEEieditemsep{\the\itemsep}% +\edef\@IEEEiedrightmargin{\the\rightmargin}% +\edef\@IEEEiedlistparindent{\the\listparindent}% +\edef\@IEEEieditemindent{\the\itemindent}} + +% Note controlled spacing here +\def\@IEEErestorelistparams{\topsep\@IEEEiedtopsep\relax% +\labelwidth\@IEEEiedlabelwidth\relax% +\labelsep\@IEEEiedlabelsep\relax% +\leftmargin\@IEEEiedleftmargin\relax% +\partopsep\@IEEEiedpartopsep\relax% +\parsep\@IEEEiedparsep\relax% +\itemsep\@IEEEieditemsep\relax% +\rightmargin\@IEEEiedrightmargin\relax% +\listparindent\@IEEEiedlistparindent\relax% +\itemindent\@IEEEieditemindent\relax} + + +% v1.6b provide original LaTeX IED list environments +% note that latex.ltx defines \itemize and \enumerate, but not \description +% which must be created by the base classes +% save original LaTeX itemize and enumerate +\let\LaTeXitemize\itemize +\let\endLaTeXitemize\enditemize +\let\LaTeXenumerate\enumerate +\let\endLaTeXenumerate\endenumerate + +% provide original LaTeX description environment from article.cls +\newenvironment{LaTeXdescription} + {\list{}{\labelwidth\z@ \itemindent-\leftmargin + \let\makelabel\descriptionlabel}} + {\endlist} +\newcommand*\descriptionlabel[1]{\hspace\labelsep + \normalfont\bfseries #1} + + +% override LaTeX's default IED lists +\def\itemize{\@IEEEitemize} +\def\enditemize{\@endIEEEitemize} +\def\enumerate{\@IEEEenumerate} +\def\endenumerate{\@endIEEEenumerate} +\def\description{\@IEEEdescription} +\def\enddescription{\@endIEEEdescription} + +% provide the user with aliases - may help those using packages that +% override itemize, enumerate, or description +\def\IEEEitemize{\@IEEEitemize} +\def\endIEEEitemize{\@endIEEEitemize} +\def\IEEEenumerate{\@IEEEenumerate} +\def\endIEEEenumerate{\@endIEEEenumerate} +\def\IEEEdescription{\@IEEEdescription} +\def\endIEEEdescription{\@endIEEEdescription} + + +% V1.6 we want to keep the IEEEtran IED list definitions as our own internal +% commands so they are protected against redefinition +\def\@IEEEitemize{\@ifnextchar[{\@@IEEEitemize}{\@@IEEEitemize[\relax]}} +\def\@IEEEenumerate{\@ifnextchar[{\@@IEEEenumerate}{\@@IEEEenumerate[\relax]}} +\def\@IEEEdescription{\@ifnextchar[{\@@IEEEdescription}{\@@IEEEdescription[\relax]}} +\def\@endIEEEitemize{\endlist} +\def\@endIEEEenumerate{\endlist} +\def\@endIEEEdescription{\endlist} + + +% DO NOT ALLOW BLANK LINES TO BE IN THESE IED ENVIRONMENTS +% AS THIS WILL FORCE NEW PARAGRAPHS AFTER THE IED LISTS +% IEEEtran itemized list MDS 1/2001 +% Note controlled spacing here, shield end of lines with % +\def\@@IEEEitemize[#1]{% + \ifnum\@itemdepth>3\relax\@toodeep\else% + \ifnum\@listdepth>5\relax\@toodeep\else% + \advance\@itemdepth\@ne% + \edef\@itemitem{labelitem\romannumeral\the\@itemdepth}% + % get the IEEElabelindentfactor for this level + \advance\@listdepth\@ne% we need to know what the level WILL be + \edef\IEEElabelindentfactor{\csname IEEElabelindentfactor\romannumeral\the\@listdepth\endcsname}% + \advance\@listdepth-\@ne% undo our increment + \def\@IEEEiedjustify{2}% right justified labels are default + % set other defaults + \IEEEnocalcleftmarginfalse% + \IEEEnolabelindentfactorfalse% + \topsep\IEEEiedtopsep% + \IEEElabelindent\IEEEilabelindent% + \labelsep\IEEEiednormlabelsep% + \partopsep 0ex% + \parsep 0ex% + \itemsep 0ex% + \rightmargin 0em% + \listparindent 0em% + \itemindent 0em% + % calculate the label width + % the user can override this later if + % they specified a \labelwidth + \settowidth{\labelwidth}{\csname labelitem\romannumeral\the\@itemdepth\endcsname}% + \@IEEEsavelistparams% save our list parameters + \list{\csname\@itemitem\endcsname}{% + \@IEEErestorelistparams% override any list{} changes + % to our globals + \let\makelabel\@IEEEiedmakelabel% v1.6b setup \makelabel + \IEEEiedlistdecl% let user alter parameters + #1\relax% + % If the user has requested not to use the + % IEEElabelindent factor, don't revise \IEEElabelindent + \ifIEEEnolabelindentfactor\relax% + \else\IEEElabelindent=\IEEElabelindentfactor\IEEElabelindent% + \fi% + % Unless the user has requested otherwise, + % calculate our left margin based + % on \IEEElabelindent, \labelwidth and + % \labelsep + \ifIEEEnocalcleftmargin\relax% + \else\IEEEcalcleftmargin{\IEEElabelindent}% + \fi}\fi\fi}% + + +% DO NOT ALLOW BLANK LINES TO BE IN THESE IED ENVIRONMENTS +% AS THIS WILL FORCE NEW PARAGRAPHS AFTER THE IED LISTS +% IEEEtran enumerate list MDS 1/2001 +% Note controlled spacing here, shield end of lines with % +\def\@@IEEEenumerate[#1]{% + \ifnum\@enumdepth>3\relax\@toodeep\else% + \ifnum\@listdepth>5\relax\@toodeep\else% + \advance\@enumdepth\@ne% + \edef\@enumctr{enum\romannumeral\the\@enumdepth}% + % get the IEEElabelindentfactor for this level + \advance\@listdepth\@ne% we need to know what the level WILL be + \edef\IEEElabelindentfactor{\csname IEEElabelindentfactor\romannumeral\the\@listdepth\endcsname}% + \advance\@listdepth-\@ne% undo our increment + \def\@IEEEiedjustify{2}% right justified labels are default + % set other defaults + \IEEEnocalcleftmarginfalse% + \IEEEnolabelindentfactorfalse% + \topsep\IEEEiedtopsep% + \IEEElabelindent\IEEEelabelindent% + \labelsep\IEEEiednormlabelsep% + \partopsep 0ex% + \parsep 0ex% + \itemsep 0ex% + \rightmargin 0em% + \listparindent 0em% + \itemindent 0em% + % calculate the label width + % We'll set it to the width suitable for all labels using + % normalfont 1) to 9) + % The user can override this later + \settowidth{\labelwidth}{9)}% + \@IEEEsavelistparams% save our list parameters + \list{\csname label\@enumctr\endcsname}{\usecounter{\@enumctr}% + \@IEEErestorelistparams% override any list{} changes + % to our globals + \let\makelabel\@IEEEiedmakelabel% v1.6b setup \makelabel + \IEEEiedlistdecl% let user alter parameters + #1\relax% + % If the user has requested not to use the + % IEEElabelindent factor, don't revise \IEEElabelindent + \ifIEEEnolabelindentfactor\relax% + \else\IEEElabelindent=\IEEElabelindentfactor\IEEElabelindent% + \fi% + % Unless the user has requested otherwise, + % calculate our left margin based + % on \IEEElabelindent, \labelwidth and + % \labelsep + \ifIEEEnocalcleftmargin\relax% + \else\IEEEcalcleftmargin{\IEEElabelindent}% + \fi}\fi\fi}% + + +% DO NOT ALLOW BLANK LINES TO BE IN THESE IED ENVIRONMENTS +% AS THIS WILL FORCE NEW PARAGRAPHS AFTER THE IED LISTS +% IEEEtran description list MDS 1/2001 +% Note controlled spacing here, shield end of lines with % +\def\@@IEEEdescription[#1]{% + \ifnum\@listdepth>5\relax\@toodeep\else% + % get the IEEElabelindentfactor for this level + \advance\@listdepth\@ne% we need to know what the level WILL be + \edef\IEEElabelindentfactor{\csname IEEElabelindentfactor\romannumeral\the\@listdepth\endcsname}% + \advance\@listdepth-\@ne% undo our increment + \def\@IEEEiedjustify{0}% left justified labels are default + % set other defaults + \IEEEnocalcleftmarginfalse% + \IEEEnolabelindentfactorfalse% + \topsep\IEEEiedtopsep% + \IEEElabelindent\IEEEdlabelindent% + % assume normal labelsep + \labelsep\IEEEiednormlabelsep% + \partopsep 0ex% + \parsep 0ex% + \itemsep 0ex% + \rightmargin 0em% + \listparindent 0em% + \itemindent 0em% + % Bogus label width in case the user forgets + % to set it. + % TIP: If you want to see what a variable's width is you + % can use the TeX command \showthe\width-variable to + % display it on the screen during compilation + % (This might be helpful to know when you need to find out + % which label is the widest) + \settowidth{\labelwidth}{Hello}% + \@IEEEsavelistparams% save our list parameters + \list{}{\@IEEErestorelistparams% override any list{} changes + % to our globals + \let\makelabel\@IEEEiedmakelabel% v1.6b setup \makelabel + \IEEEiedlistdecl% let user alter parameters + #1\relax% + % If the user has requested not to use the + % labelindent factor, don't revise \IEEElabelindent + \ifIEEEnolabelindentfactor\relax% + \else\IEEElabelindent=\IEEElabelindentfactor\IEEElabelindent% + \fi% + % Unless the user has requested otherwise, + % calculate our left margin based + % on \IEEElabelindent, \labelwidth and + % \labelsep + \ifIEEEnocalcleftmargin\relax% + \else\IEEEcalcleftmargin{\IEEElabelindent}\relax% + \fi}\fi} + +% v1.6b we use one makelabel that does justification as needed. +\def\@IEEEiedmakelabel#1{\relax\if\@IEEEiedjustify 0\relax +\makebox[\labelwidth][l]{\normalfont #1}\else +\if\@IEEEiedjustify 1\relax +\makebox[\labelwidth][c]{\normalfont #1}\else +\makebox[\labelwidth][r]{\normalfont #1}\fi\fi} + + +% compsoc uses a larger value for the normal labelsep +% and also extra spacing above and below each list +\ifCLASSOPTIONcompsoc + \IEEEiednormlabelsep 1.2em + \IEEEiedtopsep 6pt plus 3pt minus 3pt +\fi + + +% VERSE and QUOTE +% V1.7 define environments with newenvironment +\newenvironment{verse}{\let\\=\@centercr + \list{}{\itemsep\z@ \itemindent -1.5em \listparindent \itemindent + \rightmargin\leftmargin\advance\leftmargin 1.5em}\item\relax} + {\endlist} +\newenvironment{quotation}{\list{}{\listparindent 1.5em \itemindent\listparindent + \rightmargin\leftmargin \parsep 0pt plus 1pt}\item\relax} + {\endlist} +\newenvironment{quote}{\list{}{\rightmargin\leftmargin}\item\relax} + {\endlist} + + +% \titlepage +% provided only for backward compatibility. \maketitle is the correct +% way to create the title page. +\def\titlepage{\@restonecolfalse\if@twocolumn\@restonecoltrue\onecolumn + \else \newpage \fi \thispagestyle{empty}\c@page\z@} +\def\endtitlepage{\if@restonecol\twocolumn \else \newpage \fi} + +% standard values from article.cls +\arraycolsep 5pt +\arrayrulewidth .4pt +\doublerulesep 2pt + +\tabcolsep 6pt +\tabbingsep 0.5em + + +%% FOOTNOTES +% +%\skip\footins 10pt plus 4pt minus 2pt +% V1.6 respond to changes in font size +% space added above the footnotes (if present) +\skip\footins 0.9\baselineskip plus 0.4\baselineskip minus 0.2\baselineskip + +% V1.6, we need to make \footnotesep responsive to changes +% in \baselineskip or strange spacings will result when in +% draft mode. Here is a little LaTeX secret - \footnotesep +% determines the height of an invisible strut that is placed +% *above* the baseline of footnotes after the first. Since +% LaTeX considers the space for characters to be 0.7\baselineskip +% above the baseline and 0.3\baselineskip below it, we need to +% use 0.7\baselineskip as a \footnotesep to maintain equal spacing +% between all the lines of the footnotes. The IEEE often uses a tad +% more, so use 0.8\baselineskip. This slightly larger value also helps +% the text to clear the footnote marks. Note that \thanks in IEEEtran +% uses its own value of \footnotesep which is set in \maketitle. +{\footnotesize +\global\footnotesep 0.8\baselineskip} + + +\skip\@mpfootins = \skip\footins +\fboxsep = 3pt +\fboxrule = .4pt +% V1.6 use 1em, then use LaTeX2e's \@makefnmark +% Note that the IEEE normally *left* aligns the footnote marks, so we don't need +% box resizing tricks here. +\long\def\@makefntext#1{\parindent 1em\indent\hbox{\@makefnmark}#1}% V1.6 use 1em +% V1.7 compsoc does not use superscipts for footnote marks +\ifCLASSOPTIONcompsoc +\def\@IEEEcompsocmakefnmark{\hbox{\normalfont\@thefnmark.\ }} +\long\def\@makefntext#1{\parindent 1em\indent\hbox{\@IEEEcompsocmakefnmark}#1} +\fi + +% The IEEE does not use footnote rules +\def\footnoterule{} + +% V1.7 for compsoc, the IEEE uses a footnote rule only for \thanks. We devise a "one-shot" +% system to implement this. +\newif\if@IEEEenableoneshotfootnoterule +\@IEEEenableoneshotfootnoterulefalse +\ifCLASSOPTIONcompsoc +\def\footnoterule{\relax\if@IEEEenableoneshotfootnoterule +\kern-5pt +\hbox to \columnwidth{\hfill\vrule width 0.5\columnwidth height 0.4pt\hfill} +\kern4.6pt +\global\@IEEEenableoneshotfootnoterulefalse +\else +\relax +\fi} +\fi + +% V1.6 do not allow LaTeX to break a footnote across multiple pages +\interfootnotelinepenalty=10000 + +% V1.6 discourage breaks within equations +% Note that amsmath normally sets this to 10000, +% but LaTeX2e normally uses 100. +\interdisplaylinepenalty=2500 + +% default allows section depth up to /paragraph +\setcounter{secnumdepth}{4} + +% technotes do not allow /paragraph +\ifCLASSOPTIONtechnote + \setcounter{secnumdepth}{3} +\fi +% neither do compsoc conferences +\@IEEEcompsocconfonly{\setcounter{secnumdepth}{3}} + + +\newcounter{section} +\newcounter{subsection}[section] +\newcounter{subsubsection}[subsection] +\newcounter{paragraph}[subsubsection] + +% used only by IEEEtran's IEEEeqnarray as other packages may +% have their own, different, implementations +\newcounter{IEEEsubequation}[equation] + +% as shown when called by user from \ref, \label and in table of contents +\def\theequation{\arabic{equation}} % 1 +\def\theIEEEsubequation{\theequation\alph{IEEEsubequation}} % 1a (used only by IEEEtran's IEEEeqnarray) +\ifCLASSOPTIONcompsoc +% compsoc is all arabic +\def\thesection{\arabic{section}} +\def\thesubsection{\thesection.\arabic{subsection}} +\def\thesubsubsection{\thesubsection.\arabic{subsubsection}} +\def\theparagraph{\thesubsubsection.\arabic{paragraph}} +\else +\def\thesection{\Roman{section}} % I +% V1.7, \mbox prevents breaks around - +\def\thesubsection{\mbox{\thesection-\Alph{subsection}}} % I-A +% V1.7 use I-A1 format used by the IEEE rather than I-A.1 +\def\thesubsubsection{\thesubsection\arabic{subsubsection}} % I-A1 +\def\theparagraph{\thesubsubsection\alph{paragraph}} % I-A1a +\fi + +% From Heiko Oberdiek. Because of the \mbox in \thesubsection, we need to +% tell hyperref to disable the \mbox command when making PDF bookmarks. +% This done already with hyperref.sty version 6.74o and later, but +% it will not hurt to do it here again for users of older versions. +\@ifundefined{pdfstringdefPreHook}{\let\pdfstringdefPreHook\@empty}{}% +\g@addto@macro\pdfstringdefPreHook{\let\mbox\relax} + + +% Main text forms (how shown in main text headings) +% V1.6, using \thesection in \thesectiondis allows changes +% in the former to automatically appear in the latter +\ifCLASSOPTIONcompsoc + \ifCLASSOPTIONconference% compsoc conference + \def\thesectiondis{\thesection.} + \def\thesubsectiondis{\thesectiondis\arabic{subsection}.} + \def\thesubsubsectiondis{\thesubsectiondis\arabic{subsubsection}.} + \def\theparagraphdis{\thesubsubsectiondis\arabic{paragraph}.} + \else% compsoc not conferencs + \def\thesectiondis{\thesection} + \def\thesubsectiondis{\thesectiondis.\arabic{subsection}} + \def\thesubsubsectiondis{\thesubsectiondis.\arabic{subsubsection}} + \def\theparagraphdis{\thesubsubsectiondis.\arabic{paragraph}} + \fi +\else% not compsoc + \def\thesectiondis{\thesection.} % I. + \def\thesubsectiondis{\Alph{subsection}.} % B. + \def\thesubsubsectiondis{\arabic{subsubsection})} % 3) + \def\theparagraphdis{\alph{paragraph})} % d) +\fi + +% just like LaTeX2e's \@eqnnum +\def\theequationdis{{\normalfont \normalcolor (\theequation)}}% (1) +% IEEEsubequation used only by IEEEtran's IEEEeqnarray +\def\theIEEEsubequationdis{{\normalfont \normalcolor (\theIEEEsubequation)}}% (1a) +% redirect LaTeX2e's equation number display and all that depend on +% it, through IEEEtran's \theequationdis +\def\@eqnnum{\theequationdis} + + + +% V1.7 provide string macros as article.cls does +\def\contentsname{Contents} +\def\listfigurename{List of Figures} +\def\listtablename{List of Tables} +\def\refname{References} +\def\indexname{Index} +\def\figurename{Fig.} +\def\tablename{TABLE} +\@IEEEcompsocconfonly{\def\figurename{Figure}} +\def\partname{Part} +\def\appendixname{Appendix} +\def\abstractname{Abstract} +% IEEE specific names +\def\IEEEkeywordsname{Index Terms} +\def\IEEEproofname{Proof} + + +% LIST OF FIGURES AND TABLES AND TABLE OF CONTENTS +% +\def\@pnumwidth{1.55em} +\def\@tocrmarg{2.55em} +\def\@dotsep{4.5} +\setcounter{tocdepth}{3} + +% adjusted some spacings here so that section numbers will not easily +% collide with the section titles. +% VIII; VIII-A; and VIII-A.1 are usually the worst offenders. +% MDS 1/2001 +\def\tableofcontents{\section*{\contentsname}\@starttoc{toc}} +\def\l@section#1#2{\addpenalty{\@secpenalty}\addvspace{1.0em plus 1pt}% + \@tempdima 2.75em \begingroup \parindent \z@ \rightskip \@pnumwidth% + \parfillskip-\@pnumwidth {\bfseries\leavevmode #1}\hfil\hbox to\@pnumwidth{\hss #2}\par% + \endgroup} +% argument format #1:level, #2:labelindent,#3:labelsep +\def\l@subsection{\@dottedtocline{2}{2.75em}{3.75em}} +\def\l@subsubsection{\@dottedtocline{3}{6.5em}{4.5em}} +% must provide \l@ defs for ALL sublevels EVEN if tocdepth +% is such as they will not appear in the table of contents +% these defs are how TOC knows what level these things are! +\def\l@paragraph{\@dottedtocline{4}{6.5em}{5.5em}} +\def\l@subparagraph{\@dottedtocline{5}{6.5em}{6.5em}} +\def\listoffigures{\section*{\listfigurename}\@starttoc{lof}} +\def\l@figure{\@dottedtocline{1}{0em}{2.75em}} +\def\listoftables{\section*{\listtablename}\@starttoc{lot}} +\let\l@table\l@figure + + +% Definitions for floats +% +% Normal Floats +% V1.8 floatsep et al. revised down by 0.15\baselineskip +% to account for the sideeffects of \topskip compensation +\floatsep 0.85\baselineskip plus 0.2\baselineskip minus 0.2\baselineskip +\textfloatsep 1.55\baselineskip plus 0.2\baselineskip minus 0.4\baselineskip +\@fptop 0pt plus 1fil +\@fpsep 0.75\baselineskip plus 2fil +\@fpbot 0pt plus 1fil +\def\topfraction{0.9} +\def\bottomfraction{0.4} +\def\floatpagefraction{0.8} +% V1.7, let top floats approach 90% of page +\def\textfraction{0.1} + +% Double Column Floats +\dblfloatsep 0.85\baselineskip plus 0.2\baselineskip minus 0.2\baselineskip + +\dbltextfloatsep 1.55\baselineskip plus 0.2\baselineskip minus 0.4\baselineskip +% Note that it would be nice if the rubber here actually worked in LaTeX2e. +% There is a long standing limitation in LaTeX, first discovered (to the best +% of my knowledge) by Alan Jeffrey in 1992. LaTeX ignores the stretchable +% portion of \dbltextfloatsep, and as a result, double column figures can and +% do result in an non-integer number of lines in the main text columns with +% underfull vbox errors as a consequence. A post to comp.text.tex +% by Donald Arseneau confirms that this had not yet been fixed in 1998. +% IEEEtran V1.6 will fix this problem for you in the titles, but it doesn't +% protect you from other double floats. Happy vspace'ing. + +\@dblfptop 0pt plus 1fil +\@dblfpsep 0.75\baselineskip plus 2fil +\@dblfpbot 0pt plus 1fil +\def\dbltopfraction{0.8} +\def\dblfloatpagefraction{0.8} +\setcounter{dbltopnumber}{4} + +\intextsep 0.85\baselineskip plus 0.2\baselineskip minus 0.2\baselineskip +\setcounter{topnumber}{2} +\setcounter{bottomnumber}{2} +\setcounter{totalnumber}{4} + + + +% article class provides these, we should too. +\newlength\abovecaptionskip +\newlength\belowcaptionskip +% but only \abovecaptionskip is used above figure captions and *below* table +% captions +\setlength\abovecaptionskip{0.5\baselineskip} +% compsoc journals are a little more generous +\ifCLASSOPTIONcompsoc\ifCLASSOPTIONjournal + \setlength\abovecaptionskip{0.75\baselineskip} +\fi\fi +\setlength\belowcaptionskip{0pt} +% V1.6 create hooks in case the caption spacing ever needs to be +% overridden by a user +\def\@IEEEfigurecaptionsepspace{\vskip\abovecaptionskip\relax}% +\def\@IEEEtablecaptionsepspace{\vskip\abovecaptionskip\relax}% + + +% 1.6b revise caption system so that \@makecaption uses two arguments +% as with LaTeX2e. Otherwise, there will be problems when using hyperref. +\def\@IEEEtablestring{table} + + +% V1.8 compensate for \topskip so top of top figures align with tops of the first lines of main text +% here we calculate a space equal to the amount \topskip exceeds the main text height +% we hook in at \@floatboxreset +\def\@IEEEfiguretopskipspace{\ifdim\prevdepth=-1000pt\relax +\setlength{\@IEEEtrantmpdimenA}{1\topskip}\relax +\addtolength{\@IEEEtrantmpdimenA}{-0.7\@IEEEnormalsizeunitybaselineskip}\relax +\vspace*{\@IEEEtrantmpdimenA}\fi} +% V1.8 compensate for \topskip at the top of top tables so caption text is on main text baseline +% use a strut set on the caption baseline within \@makecaption +\def\@IEEEtabletopskipstrut{\ifdim\prevdepth=-1000pt\rule{0pt}{\topskip}\fi} +% the \ifdim\prevdepth checks are always expected to be true for IEEE style float caption ordering +% because top of figure content and top of captions in tables is the first thing on the vertical +% list of these floats +% thanks to Donald Arseneau for his 2000/11/11 post "Re: caption hacking" with info on this topic. + + +\ifCLASSOPTIONcompsoc +% V1.7 compsoc \@makecaption +\ifCLASSOPTIONconference% compsoc conference +\long\def\@makecaption#1#2{% +% test if is a for a figure or table +\ifx\@captype\@IEEEtablestring% +% if a table, do table caption +\footnotesize\bgroup\par\centering\@IEEEtabletopskipstrut{\normalfont\footnotesize {#1.}\nobreakspace\scshape #2}\par\addvspace{0.5\baselineskip}\egroup% +\@IEEEtablecaptionsepspace +% if not a table, format it as a figure +\else +\@IEEEfigurecaptionsepspace +\setbox\@tempboxa\hbox{\normalfont\footnotesize {#1.}\nobreakspace #2}% +\ifdim \wd\@tempboxa >\hsize% +% if caption is longer than a line, let it wrap around +\setbox\@tempboxa\hbox{\normalfont\footnotesize {#1.}\nobreakspace}% +\parbox[t]{\hsize}{\normalfont\footnotesize \noindent\unhbox\@tempboxa#2}% +% if caption is shorter than a line, center +\else% +\hbox to\hsize{\normalfont\footnotesize\hfil\box\@tempboxa\hfil}% +\fi\fi} +% +\else% nonconference compsoc +\long\def\@makecaption#1#2{% +% test if is a for a figure or table +\ifx\@captype\@IEEEtablestring% +% if a table, do table caption +\footnotesize\bgroup\par\centering\@IEEEtabletopskipstrut{\normalfont\sffamily\footnotesize #1}\\{\normalfont\sffamily\footnotesize #2}\par\addvspace{0.5\baselineskip}\egroup% +\@IEEEtablecaptionsepspace +% if not a table, format it as a figure +\else +\@IEEEfigurecaptionsepspace +\setbox\@tempboxa\hbox{\normalfont\sffamily\footnotesize {#1.}\nobreakspace #2}% +\ifdim \wd\@tempboxa >\hsize% +% if caption is longer than a line, let it wrap around +\setbox\@tempboxa\hbox{\normalfont\sffamily\footnotesize {#1.}\nobreakspace}% +\parbox[t]{\hsize}{\normalfont\sffamily\footnotesize \noindent\unhbox\@tempboxa#2}% +% if caption is shorter than a line, left justify +\else% +\hbox to\hsize{\normalfont\sffamily\footnotesize\box\@tempboxa\hfil}% +\fi\fi} +\fi +% +\else% traditional noncompsoc \@makecaption +\long\def\@makecaption#1#2{% +% test if is a for a figure or table +\ifx\@captype\@IEEEtablestring% +% if a table, do table caption +\footnotesize\bgroup\par\centering\@IEEEtabletopskipstrut{\normalfont\footnotesize #1}\\{\normalfont\footnotesize\scshape #2}\par\addvspace{0.5\baselineskip}\egroup% +\@IEEEtablecaptionsepspace +% if not a table, format it as a figure +\else +\@IEEEfigurecaptionsepspace +% 3/2001 use footnotesize, not small; use two nonbreaking spaces, not one +\setbox\@tempboxa\hbox{\normalfont\footnotesize {#1.}\nobreakspace\nobreakspace #2}% +\ifdim \wd\@tempboxa >\hsize% +% if caption is longer than a line, let it wrap around +\setbox\@tempboxa\hbox{\normalfont\footnotesize {#1.}\nobreakspace\nobreakspace}% +\parbox[t]{\hsize}{\normalfont\footnotesize\noindent\unhbox\@tempboxa#2}% +% if caption is shorter than a line, center if conference, left justify otherwise +\else% +\ifCLASSOPTIONconference \hbox to\hsize{\normalfont\footnotesize\hfil\box\@tempboxa\hfil}% +\else \hbox to\hsize{\normalfont\footnotesize\box\@tempboxa\hfil}% +\fi\fi\fi} +\fi + + + +% V1.7 disable captions class option, do so in a way that retains operation of \label +% within \caption +\ifCLASSOPTIONcaptionsoff +\long\def\@makecaption#1#2{\vspace*{2em}\footnotesize\bgroup\par\addvspace{0.5\baselineskip}\centering{\footnotesize #1}\par\addvspace{0.5\baselineskip}\egroup% +\let\@IEEEtemporiglabeldefsave\label +\let\@IEEEtemplabelargsave\relax +\def\label##1{\gdef\@IEEEtemplabelargsave{##1}}% +\setbox\@tempboxa\hbox{#2}% +\let\label\@IEEEtemporiglabeldefsave +\ifx\@IEEEtemplabelargsave\relax\else\label{\@IEEEtemplabelargsave}\fi} +\fi + + +% V1.7 define end environments with \def not \let so as to work OK with +% preview-latex +\newcounter{figure} +\def\thefigure{\@arabic\c@figure} +\def\fps@figure{tbp} +\def\ftype@figure{1} +\def\ext@figure{lof} +\def\fnum@figure{\figurename\nobreakspace\thefigure} +% V1.8 within figures add \@IEEEfiguretopskipspace compensation to LaTeX2e's \@floatboxreset +\def\figure{\def\@floatboxreset{\reset@font\normalsize\@setminipage\@IEEEfiguretopskipspace}\@float{figure}} +\def\endfigure{\end@float} +% V1.8 also add \@IEEEfiguretopskipspace compensation to \figure* +\@namedef{figure*}{\def\@floatboxreset{\reset@font\normalsize\@setminipage\@IEEEfiguretopskipspace}\@dblfloat{figure}} +\@namedef{endfigure*}{\end@dblfloat} + +\newcounter{table} +\ifCLASSOPTIONcompsoc +\def\thetable{\arabic{table}} +\else +\def\thetable{\@Roman\c@table} +\fi +\def\fps@table{tbp} +\def\ftype@table{2} +\def\ext@table{lot} +\def\fnum@table{\tablename\nobreakspace\thetable} +% V1.6 The IEEE uses 8pt text for tables +% within tables alter LaTeX2e's \@floatboxreset to use \footnotesize +\def\table{\def\@floatboxreset{\reset@font\footnotesize\@setminipage}\@float{table}} +\def\endtable{\end@float} +% v1.6b double column tables need to default to footnotesize as well. +\@namedef{table*}{\def\@floatboxreset{\reset@font\footnotesize\@setminipage}\@dblfloat{table}} +\@namedef{endtable*}{\end@dblfloat} + + + + +%% -- Command Argument Scanning Support Functions -- +%% V1.8a + +% usage: \@IEEEstripouterbraces*{} +% \@IEEEstripouterbraces fully expands its argument (which it then stores +% in \@IEEEstripouterbracesarg) via \edef, then removes any outer enclosing +% braces, and finally stores the result in the macro +% \@IEEEstrippedouterbraces. +% +% For example: +% \@IEEEstripouterbraces{{{{ab}c}}} +% results in: +% +% \@IEEEstripouterbracesarg ==> a macro containing {{{ab}c}} +% \@IEEEstrippedouterbraces ==> a macro containing {ab}c +% +% the *-star form,\@IEEEstripouterbraces*, does not expand the argument +% contents during processing +\def\@IEEEstripouterbraces{\@ifstar{\let\@IEEEstripouterbracesdef=\def\@@IEEEstripouterbraces}{\let\@IEEEstripouterbracesdef=\edef\@@IEEEstripouterbraces}} + +\def\@@IEEEstripouterbraces#1{\@IEEEstripouterbracesdef\@IEEEstripouterbracesarg{#1}\relax +% If the macro is unchanged after being acquired as a single delimited +% argument, we know we have one sequence of tokens without any enclosing +% braces. Loop until this is true. +\loop + \expandafter\@@@IEEEstripouterbraces\@IEEEstripouterbracesarg\@IEEEgeneralsequenceDELIMITER +\ifx\@IEEEstrippedouterbraces\@IEEEstripouterbracesarg +\else + \let\@IEEEstripouterbracesarg\@IEEEstrippedouterbraces +\repeat} + +\def\@@@IEEEstripouterbraces#1\@IEEEgeneralsequenceDELIMITER{\def\@IEEEstrippedouterbraces{#1}} + + + +% usage: \@IEEEextractgroup*{} +% \@IEEEextractgroup fully expands its argument (which it then stores in +% \@IEEEextractgrouparg) via \edef and then assigns the first "brace group" +% of tokens to the macro \@IEEEextractedgroup. +% The remaining groups, if any, are stored in the macro +% \@IEEEextractedgroupremain. If the argument does not contain the requisite +% groups, the respective macros will be defined to be empty. +% There is an asymmetry in that \@IEEEextractedgroup is stripped of its first +% outer grouping while \@IEEEextractedgroupremain retains even the outer +% grouping (if present) that originally identified it as a group. +% +% For example: +% \@IEEEextractgroup{{{ab}}{c{de}}} +% results in: +% +% \@IEEEextractgrouparg ==> a macro containing {{ab}}{c{de}} +% \@IEEEextractedgroup ==> a macro containing {ab} +% \@IEEEextractedgroupremain ==> a macro containing {c{de}} +% +% The *-star form, \@IEEEextractgroup*, does not expand its argument +% contents during processing. +\def\@IEEEextractgroup{\@ifstar{\let\@IEEEextractgroupdef=\def\@@IEEEextractgroup}{\let\@IEEEextractgroupdef=\edef\@@IEEEextractgroup}} + +\def\@@IEEEextractgroup#1{\@IEEEextractgroupdef\@IEEEextractgrouparg{#1}\relax +% trap the case of an empty extracted group as this would cause problems with +% \@IEEEextractgroupremain's argument acquisition +\ifx\@IEEEextractgrouparg\@empty + \def\@IEEEextractedgroup{}\relax + \def\@IEEEextractedgroupremain{}\relax +\else + % We have to use some dirty tricks here. We want to insert {} around + % whatever remains after the first group so that TeX's argument scanner + % will preserve any originally enclosing braces as well as provide an + % empty argument to acquire even if there isn't a second group. + % In this first of two dirty tricks, we put a } at the end of the structure + % we are going to extract from. The \ifnum0=`{\fi keeps TeX happy to allow + % what would otherwise be an unbalanced macro definition for + % \@@IEEEextractgroup to be acceptable to it. + \ifnum0=`{\fi\expandafter\@IEEEextractgroupremain\@IEEEextractgrouparg}\relax +\fi} + +% In the second part of the dirty tricks, we insert a leading { right after +% the first group is acquired, but before the remainder is. Again, the +% \ifnum0=`}\fi keeps TeX happy during definition time, but will disappear +% during run time. +\def\@IEEEextractgroupremain#1{\def\@IEEEextractedgroup{#1}\expandafter\@@IEEEextractgroupremain\expandafter{\ifnum0=`}\fi} + +\def\@@IEEEextractgroupremain#1{\def\@IEEEextractedgroupremain{#1}} + + + +% \@IEEEextracttoken relocated at top because margin setting commands rely on it + + + +% usage: \@IEEEextracttokengroups*{} +% \@IEEEextracttokengroups fully expands its argument (which it then stores +% in \@IEEEextracttokengroupsarg) and then assigns the first "brace group" of +% tokens (with the outermost braces removed) to the macro +% \@IEEEextractedfirstgroup. +% The meaning of the first nonbrace (but including the empty group) token +% within this first group is assigned via \let to \@IEEEextractedfirsttoken +% as well as stored in the macro \@IEEEextractedfirsttokenmacro. If a first +% nonbrace token does not exist (or is an empty group), these will be \relax +% and empty, respectively. Tokens that would otherwise be discarded during +% the acquisition of the first token in the first group are stored in +% \@IEEEextractedfirsttokensdiscarded, however their original relative brace +% nesting depths are not guaranteed to be preserved. +% The first group within this first group is stored in the macro +% \@IEEEextractedfirstfirstgroup. +% Likewise for the next group after the first: \@IEEEextractednextgroup, +% \@IEEEextractednextfirstgroup, \@IEEEextractednextgroupfirsttoken, +% \@IEEEextractednextgroupfirsttokenmacro, and +% \@IEEEextractednextfirsttokensdiscarded. +% All tokens/groups after the first group, including any enclosing braces, +% are stored in the macro \@IEEEextractedafterfirstgroupremain which will +% be empty if none exist. +% +% For example: +% \@IEEEextracttokengroups{{{ab}{cd}}{{ef}g}} +% will result in: +% +% \@IEEEextracttokengroupsarg ==> a macro containing {{ab}{cd}}{{ef}g} +% \@IEEEextractedfirstgroup ==> a macro containing {ab}{cd} +% \@IEEEextractedafterfirstgroupremain ==> a macro containing {{ef}g} +% \@IEEEextractedfirsttoken ==> the letter a +% \@IEEEextractedfirsttokenmacro ==> a macro containing a +% \@IEEEextractedfirsttokensdiscarded ==> a macro containing bcd +% \@IEEEextractedfirstfirstgroup ==> a macro containing ab +% \@IEEEextractednextgroup ==> a macro containing {ef}g +% \@IEEEextractednextfirsttoken ==> the letter e +% \@IEEEextractednextfirsttokenmacro ==> a macro containing e +% \@IEEEextractednextfirsttokensdiscarded ==> a macro containing fg +% \@IEEEextractednextfirstgroup ==> a macro containing ef +% +% If given an empty argument, \@IEEEextractedfirsttoken and +% \@IEEEextractednextfirsttoken will be set to \relax +% and all the macros will be empty. +% the *-star form, \@IEEEextracttokengroups*, does not expand its argument +% contents during processing. +% +% Depends on: \@IEEEextractgroup, \@IEEEextracttoken +\def\@IEEEextracttokengroups{\@ifstar{\let\@IEEEextracttokengroupsdef=\def\@@IEEEextracttokengroups}{\let\@IEEEextracttokengroupsdef=\edef\@@IEEEextracttokengroups}} +\def\@@IEEEextracttokengroups#1{\@IEEEextracttokengroupsdef\@IEEEextracttokengroupsarg{#1}\relax +% begin extraction, these functions are safe with empty arguments +% first group +\expandafter\@IEEEextractgroup\expandafter*\expandafter{\@IEEEextracttokengroupsarg}\relax +\let\@IEEEextractedfirstgroup\@IEEEextractedgroup +\let\@IEEEextractedafterfirstgroupremain\@IEEEextractedgroupremain +\expandafter\@IEEEextracttoken\expandafter*\expandafter{\@IEEEextractedfirstgroup}\relax +\let\@IEEEextractedfirsttoken\@IEEEextractedtoken +\let\@IEEEextractedfirsttokenmacro\@IEEEextractedtokenmacro +\let\@IEEEextractedfirsttokensdiscarded\@IEEEextractedtokensdiscarded +% first first group +\expandafter\@IEEEextractgroup\expandafter*\expandafter{\@IEEEextractedfirstgroup}\relax +\let\@IEEEextractedfirstfirstgroup\@IEEEextractedgroup +% next group +\expandafter\@IEEEextractgroup\expandafter*\expandafter{\@IEEEextractedafterfirstgroupremain}\relax +\let\@IEEEextractednextgroup\@IEEEextractedgroup +\expandafter\@IEEEextracttoken\expandafter*\expandafter{\@IEEEextractednextgroup}\relax +\let\@IEEEextractednextfirsttoken\@IEEEextractedtoken +\let\@IEEEextractednextfirsttokenmacro\@IEEEextractedtokenmacro +\let\@IEEEextractednextfirsttokensdiscarded\@IEEEextractedtokensdiscarded +% next first group +\expandafter\@IEEEextractgroup\expandafter*\expandafter{\@IEEEextractednextgroup}\relax +\let\@IEEEextractednextfirstgroup\@IEEEextractedgroup} + + +%% -- End of Command Argument Scanning Support Functions -- + + + + +%% +%% START OF IEEEeqnarray DEFINITIONS +%% +%% Inspired by the concepts, examples, and previous works of LaTeX +%% coders and developers such as Donald Arseneau, Fred Bartlett, +%% David Carlisle, Tony Liu, Frank Mittelbach, Piet van Oostrum, +%% Roland Winkler and Mark Wooding. +%% I don't make the claim that my work here is even near their calibre. ;) + + +\newif\if@IEEEeqnarrayboxnojot% flag to indicate if the environment was called as the star form +\@IEEEeqnarrayboxnojotfalse + +\newif\if@advanceIEEEeqncolcnt% tracks if the environment should advance the col counter +% allows a way to make an \IEEEeqnarraybox that can be used within an \IEEEeqnarray +% used by IEEEeqnarraymulticol so that it can work properly in both +\@advanceIEEEeqncolcnttrue + +\newcount\@IEEEeqnnumcols % tracks how many IEEEeqnarray cols are defined +\newcount\@IEEEeqncolcnt % tracks how many IEEEeqnarray cols the user actually used + + +% The default math style used by the columns +\def\IEEEeqnarraymathstyle{\displaystyle} +% The default text style used by the columns +% default to using the current font +\def\IEEEeqnarraytextstyle{\relax} + +% like the iedlistdecl but for \IEEEeqnarray +\def\IEEEeqnarraydecl{\relax} +\def\IEEEeqnarrayboxdecl{\relax} + + + +% V1.8 flags to indicate that equation numbering is to persist +\newif\if@IEEEeqnumpersist% +\@IEEEeqnumpersistfalse +\newif\if@IEEEsubeqnumpersist% +\@IEEEsubeqnumpersistfalse +% +% V1.8 flags to indicate if (sub)equation number of last line was preadvanced +\newif\if@IEEEeqnumpreadv% +\@IEEEeqnumpreadvfalse +\newif\if@IEEEsubeqnumpreadv% +\@IEEEsubeqnumpreadvfalse + +\newcount\@IEEEsubeqnnumrollback% saves previous value of IEEEsubequation number in case we need to restore it + +% \yesnumber is the opposite of \nonumber +% a novel concept with the same def as the equationarray package +% However, we give IEEE versions too since some LaTeX packages such as +% the MDWtools mathenv.sty redefine \nonumber to something else. +% This command is intended for use in non-IEEEeqnarray math environments +\providecommand{\yesnumber}{\global\@eqnswtrue} + + +% IEEEyes/nonumber +% V1.8 add persistant * forms +% These commands can alter the type of equation an IEEEeqnarray line is. +\def\IEEEyesnumber{\@ifstar{\global\@IEEEeqnumpersisttrue\global\@IEEEsubeqnumpersistfalse\@IEEEyesnumber}{\@IEEEyesnumber}} + +\def\@IEEEyesnumber{\global\@eqnswtrue +\if@IEEEeqnarrayISinner% alter counters and label only inside an IEEEeqnarray +\ifnum\c@IEEEsubequation>0\relax + \stepcounter{equation}\setcounter{IEEEsubequation}{0}\gdef\@currentlabel{\p@equation\theequation}\relax + \gdef\@currentHref{\@IEEEtheHrefequation}% setup hyperref label +\fi +% even if we reached this eqn num via a preadv, it is legit now +\global\@IEEEeqnumpreadvfalse\global\@IEEEsubeqnumpreadvfalse +\fi} + +\def\IEEEnonumber{\@ifstar{\global\@IEEEeqnumpersistfalse\global\@IEEEsubeqnumpersistfalse\global\@eqnswfalse}{\global\@eqnswfalse}} + + +\def\IEEEyessubnumber{\@ifstar{\global\@IEEEsubeqnumpersisttrue\@IEEEyessubnumber}{\@IEEEyessubnumber}} +% +\def\@IEEEyessubnumber{\if@IEEEeqnarrayISinner% alter counters and label only inside an IEEEeqnarray + \ifnum\c@IEEEsubequation>0\relax% if it already is a subequation, we are good to go as-is + \else% if we are a regular equation we have to watch out for two cases + \if@IEEEeqnumpreadv% if this equation is the result of a preadvance, backout and bump the sub eqnnum + \global\advance\c@equation\m@ne\global\c@IEEEsubequation=\@IEEEsubeqnnumrollback\addtocounter{IEEEsubequation}{1}\relax + \else% non-preadvanced equations just need initialization of their sub eqnnum + \setcounter{IEEEsubequation}{1}\relax + \fi + \fi% fi already is subequation + \gdef\@currentlabel{\p@IEEEsubequation\theIEEEsubequation}\relax + \gdef\@currentHref{\@IEEEtheHrefsubequation}% setup hyperref label + \global\@IEEEeqnumpreadvfalse\global\@IEEEsubeqnumpreadvfalse% no longer a preadv anymore + \global\@eqnswtrue +\fi} + + +\def\IEEEnosubnumber{\@ifstar{\global\@IEEEsubeqnumpersistfalse\@IEEEnosubnumber}{\@IEEEnosubnumber}} +% +\def\@IEEEnosubnumber{\if@IEEEeqnarrayISinner% alter counters and label only inside an IEEEeqnarray + \if@eqnsw % we do nothing unless we know we will display because we play with the counters here + % if it currently is a subequation, bump up to the next equation number and turn off the subequation + \ifnum\c@IEEEsubequation>0\relax\addtocounter{equation}{1}\setcounter{IEEEsubequation}{0}\relax + \fi + \global\@IEEEeqnumpreadvfalse\global\@IEEEsubeqnumpreadvfalse% no longer a preadv anymore + \gdef\@currentlabel{\p@equation\theequation}\relax + \gdef\@currentHref{\@IEEEtheHrefequation}% setup hyperref label + \fi +\fi} + + + +% allows users to "push away" equations that get too close to the equation numbers +\def\IEEEeqnarraynumspace{\hphantom{\ifnum\c@IEEEsubequation>0\relax\theIEEEsubequationdis\else\theequationdis\fi}} + +% provides a way to span multiple columns within IEEEeqnarray environments +% will consider \if@advanceIEEEeqncolcnt before globally advancing the +% column counter - so as to work within \IEEEeqnarraybox +% usage: \IEEEeqnarraymulticol{number cols. to span}{col type}{cell text} +\long\def\IEEEeqnarraymulticol#1#2#3{\multispan{#1}\relax +% check if column is defined for the precolumn definition +% We have to be careful here because TeX scans for & even within an \iffalse +% where it does not expand macros. So, if we used only one \ifx and a #3 +% appeared in the false branch and the user inserted another alignment +% structure that uses & in the \IEEEeqnarraymulticol{}, TeX will not see that +% there is an inner alignment in the false branch yet still will see any & +% there and will think that they apply to the outer alignment resulting in an +% incomplete \ifx error. +% So, here we use separate checks for the pre and post parts in order to keep +% the #3 outside of all conditionals. +\relax\expandafter\ifx\csname @IEEEeqnarraycolDEF#2\endcsname\@IEEEeqnarraycolisdefined\relax +\csname @IEEEeqnarraycolPRE#2\endcsname +\else% if not, error and use default type +\@IEEEclspkgerror{Invalid column type "#2" in \string\IEEEeqnarraymulticol.\MessageBreak +Using a default centering column instead}% +{You must define IEEEeqnarray column types before use.}% +\csname @IEEEeqnarraycolPRE@IEEEdefault\endcsname +\fi +% The ten \relax are to help prevent misleading error messages in case a user +% accidently inserted a macro that tries to acquire additional arguments. +#3\relax\relax\relax\relax\relax\relax\relax\relax\relax\relax +% check if column is defined for the postcolumn definition +\expandafter\ifx\csname @IEEEeqnarraycolDEF#2\endcsname\@IEEEeqnarraycolisdefined\relax +\csname @IEEEeqnarraycolPOST#2\endcsname +\else% if not, use the default type +\csname @IEEEeqnarraycolPOST@IEEEdefault\endcsname +\fi +% advance column counter only if the IEEEeqnarray environment wants it +\if@advanceIEEEeqncolcnt\global\advance\@IEEEeqncolcnt by #1\relax\fi} + +% like \omit, but maintains track of the column counter for \IEEEeqnarray +\def\IEEEeqnarrayomit{\omit\if@advanceIEEEeqncolcnt\global\advance\@IEEEeqncolcnt by 1\relax\fi} + + +% provides a way to define a letter referenced column type +% usage: \IEEEeqnarraydefcol{col. type letter/name}{pre insertion text}{post insertion text} +\def\IEEEeqnarraydefcol#1#2#3{\expandafter\def\csname @IEEEeqnarraycolPRE#1\endcsname{#2}% +\expandafter\def\csname @IEEEeqnarraycolPOST#1\endcsname{#3}% +\expandafter\def\csname @IEEEeqnarraycolDEF#1\endcsname{1}} + + +% provides a way to define a numerically referenced inter-column glue types +% usage: \IEEEeqnarraydefcolsep{col. glue number}{glue definition} +\def\IEEEeqnarraydefcolsep#1#2{\expandafter\def\csname @IEEEeqnarraycolSEP\romannumeral #1\endcsname{#2}% +\expandafter\def\csname @IEEEeqnarraycolSEPDEF\romannumeral #1\endcsname{1}} + + +\def\@IEEEeqnarraycolisdefined{1}% just a macro for 1, used for checking undefined column types + + +% expands and appends the given argument to the \@IEEEtrantmptoksA token list +% used to build up the \halign preamble +\def\@IEEEappendtoksA#1{\edef\@@IEEEappendtoksA{\@IEEEtrantmptoksA={\the\@IEEEtrantmptoksA #1}}% +\@@IEEEappendtoksA} + +% also appends to \@IEEEtrantmptoksA, but does not expand the argument +% uses \toks8 as a scratchpad register +\def\@IEEEappendNOEXPANDtoksA#1{\toks8={#1}% +\edef\@@IEEEappendNOEXPANDtoksA{\@IEEEtrantmptoksA={\the\@IEEEtrantmptoksA\the\toks8}}% +\@@IEEEappendNOEXPANDtoksA} + +% define some common column types for the user +% math +\IEEEeqnarraydefcol{l}{$\IEEEeqnarraymathstyle}{$\hfil} +\IEEEeqnarraydefcol{c}{\hfil$\IEEEeqnarraymathstyle}{$\hfil} +\IEEEeqnarraydefcol{r}{\hfil$\IEEEeqnarraymathstyle}{$} +\IEEEeqnarraydefcol{L}{$\IEEEeqnarraymathstyle{}}{{}$\hfil} +\IEEEeqnarraydefcol{C}{\hfil$\IEEEeqnarraymathstyle{}}{{}$\hfil} +\IEEEeqnarraydefcol{R}{\hfil$\IEEEeqnarraymathstyle{}}{{}$} +% text +\IEEEeqnarraydefcol{s}{\IEEEeqnarraytextstyle}{\hfil} +\IEEEeqnarraydefcol{t}{\hfil\IEEEeqnarraytextstyle}{\hfil} +\IEEEeqnarraydefcol{u}{\hfil\IEEEeqnarraytextstyle}{} + +% vertical rules +\IEEEeqnarraydefcol{v}{}{\vrule width\arrayrulewidth} +\IEEEeqnarraydefcol{vv}{\vrule width\arrayrulewidth\hfil}{\hfil\vrule width\arrayrulewidth} +\IEEEeqnarraydefcol{V}{}{\vrule width\arrayrulewidth\hskip\doublerulesep\vrule width\arrayrulewidth} +\IEEEeqnarraydefcol{VV}{\vrule width\arrayrulewidth\hskip\doublerulesep\vrule width\arrayrulewidth\hfil}% +{\hfil\vrule width\arrayrulewidth\hskip\doublerulesep\vrule width\arrayrulewidth} + +% horizontal rules +\IEEEeqnarraydefcol{h}{}{\leaders\hrule height\arrayrulewidth\hfil} +\IEEEeqnarraydefcol{H}{}{\leaders\vbox{\hrule width\arrayrulewidth\vskip\doublerulesep\hrule width\arrayrulewidth}\hfil} + +% plain +\IEEEeqnarraydefcol{x}{}{} +\IEEEeqnarraydefcol{X}{$}{$} + +% the default column type to use in the event a column type is not defined +\IEEEeqnarraydefcol{@IEEEdefault}{\hfil$\IEEEeqnarraymathstyle}{$\hfil} + + +% a zero tabskip (used for "-" col types) +\def\@IEEEeqnarraycolSEPzero{0pt plus 0pt minus 0pt} +% a centering tabskip (used for "+" col types) +\def\@IEEEeqnarraycolSEPcenter{1000pt plus 0pt minus 1000pt} + +% top level default tabskip glues for the start, end, and inter-column +% may be reset within environments not always at the top level, e.g., \IEEEeqnarraybox +\edef\@IEEEeqnarraycolSEPdefaultstart{\@IEEEeqnarraycolSEPcenter}% default start glue +\edef\@IEEEeqnarraycolSEPdefaultend{\@IEEEeqnarraycolSEPcenter}% default end glue +\edef\@IEEEeqnarraycolSEPdefaultmid{\@IEEEeqnarraycolSEPzero}% default inter-column glue + + + +% creates a vertical rule that extends from the bottom to the top a a cell +% Provided in case other packages redefine \vline some other way. +% usage: \IEEEeqnarrayvrule[rule thickness] +% If no argument is provided, \arrayrulewidth will be used for the rule thickness. +\newcommand\IEEEeqnarrayvrule[1][\arrayrulewidth]{\vrule\@width#1\relax} + +% creates a blank separator row +% usage: \IEEEeqnarrayseprow[separation length][font size commands] +% default is \IEEEeqnarrayseprow[0.25\normalbaselineskip][\relax] +% blank arguments inherit the default values +% uses \skip5 as a scratch register - calls \@IEEEeqnarraystrutsize which uses more scratch registers +\def\IEEEeqnarrayseprow{\relax\@ifnextchar[{\@IEEEeqnarrayseprow}{\@IEEEeqnarrayseprow[0.25\normalbaselineskip]}} +\def\@IEEEeqnarrayseprow[#1]{\relax\@ifnextchar[{\@@IEEEeqnarrayseprow[#1]}{\@@IEEEeqnarrayseprow[#1][\relax]}} +\def\@@IEEEeqnarrayseprow[#1][#2]{\def\@IEEEeqnarrayseprowARGONE{#1}% +\ifx\@IEEEeqnarrayseprowARGONE\@empty% +% get the skip value, based on the font commands +% use skip5 because \IEEEeqnarraystrutsize uses \skip0, \skip2, \skip3 +% assign within a bogus box to confine the font changes +{\setbox0=\hbox{#2\relax\global\skip5=0.25\normalbaselineskip}}% +\else% +{\setbox0=\hbox{#2\relax\global\skip5=#1}}% +\fi% +\@IEEEeqnarrayhoptolastcolumn\IEEEeqnarraystrutsize{\skip5}{0pt}[\relax]\relax} + +% creates a blank separator row, but omits all the column templates +% usage: \IEEEeqnarrayseprowcut[separation length][font size commands] +% default is \IEEEeqnarrayseprowcut[0.25\normalbaselineskip][\relax] +% blank arguments inherit the default values +% uses \skip5 as a scratch register - calls \@IEEEeqnarraystrutsize which uses more scratch registers +\def\IEEEeqnarrayseprowcut{\multispan{\@IEEEeqnnumcols}\relax% span all the cols +% advance column counter only if the IEEEeqnarray environment wants it +\if@advanceIEEEeqncolcnt\global\advance\@IEEEeqncolcnt by \@IEEEeqnnumcols\relax\fi% +\@ifnextchar[{\@IEEEeqnarrayseprowcut}{\@IEEEeqnarrayseprowcut[0.25\normalbaselineskip]}} +\def\@IEEEeqnarrayseprowcut[#1]{\relax\@ifnextchar[{\@@IEEEeqnarrayseprowcut[#1]}{\@@IEEEeqnarrayseprowcut[#1][\relax]}} +\def\@@IEEEeqnarrayseprowcut[#1][#2]{\def\@IEEEeqnarrayseprowARGONE{#1}% +\ifx\@IEEEeqnarrayseprowARGONE\@empty% +% get the skip value, based on the font commands +% use skip5 because \IEEEeqnarraystrutsize uses \skip0, \skip2, \skip3 +% assign within a bogus box to confine the font changes +{\setbox0=\hbox{#2\relax\global\skip5=0.25\normalbaselineskip}}% +\else% +{\setbox0=\hbox{#2\relax\global\skip5=#1}}% +\fi% +\IEEEeqnarraystrutsize{\skip5}{0pt}[\relax]\relax} + + + +% draws a single rule across all the columns optional +% argument determines the rule width, \arrayrulewidth is the default +% updates column counter as needed and turns off struts +% usage: \IEEEeqnarrayrulerow[rule line thickness] +\def\IEEEeqnarrayrulerow{\multispan{\@IEEEeqnnumcols}\relax% span all the cols +% advance column counter only if the IEEEeqnarray environment wants it +\if@advanceIEEEeqncolcnt\global\advance\@IEEEeqncolcnt by \@IEEEeqnnumcols\relax\fi% +\@ifnextchar[{\@IEEEeqnarrayrulerow}{\@IEEEeqnarrayrulerow[\arrayrulewidth]}} +\def\@IEEEeqnarrayrulerow[#1]{\leaders\hrule height#1\hfil\relax% put in our rule +% turn off any struts +\IEEEeqnarraystrutsize{0pt}{0pt}[\relax]\relax} + + +% draws a double rule by using a single rule row, a separator row, and then +% another single rule row +% first optional argument determines the rule thicknesses, \arrayrulewidth is the default +% second optional argument determines the rule spacing, \doublerulesep is the default +% usage: \IEEEeqnarraydblrulerow[rule line thickness][rule spacing] +\def\IEEEeqnarraydblrulerow{\multispan{\@IEEEeqnnumcols}\relax% span all the cols +% advance column counter only if the IEEEeqnarray environment wants it +\if@advanceIEEEeqncolcnt\global\advance\@IEEEeqncolcnt by \@IEEEeqnnumcols\relax\fi% +\@ifnextchar[{\@IEEEeqnarraydblrulerow}{\@IEEEeqnarraydblrulerow[\arrayrulewidth]}} +\def\@IEEEeqnarraydblrulerow[#1]{\relax\@ifnextchar[{\@@IEEEeqnarraydblrulerow[#1]}% +{\@@IEEEeqnarraydblrulerow[#1][\doublerulesep]}} +\def\@@IEEEeqnarraydblrulerow[#1][#2]{\def\@IEEEeqnarraydblrulerowARG{#1}% +% we allow the user to say \IEEEeqnarraydblrulerow[][] +\ifx\@IEEEeqnarraydblrulerowARG\@empty% +\@IEEEeqnarrayrulerow[\arrayrulewidth]% +\else% +\@IEEEeqnarrayrulerow[#1]\relax% +\fi% +\def\@IEEEeqnarraydblrulerowARG{#2}% +\ifx\@IEEEeqnarraydblrulerowARG\@empty% +\\\IEEEeqnarrayseprow[\doublerulesep][\relax]% +\else% +\\\IEEEeqnarrayseprow[#2][\relax]% +\fi% +\\\multispan{\@IEEEeqnnumcols}% +% advance column counter only if the IEEEeqnarray environment wants it +\if@advanceIEEEeqncolcnt\global\advance\@IEEEeqncolcnt by \@IEEEeqnnumcols\relax\fi% +\def\@IEEEeqnarraydblrulerowARG{#1}% +\ifx\@IEEEeqnarraydblrulerowARG\@empty% +\@IEEEeqnarrayrulerow[\arrayrulewidth]% +\else% +\@IEEEeqnarrayrulerow[#1]% +\fi% +} + +% draws a double rule by using a single rule row, a separator (cutting) row, and then +% another single rule row +% first optional argument determines the rule thicknesses, \arrayrulewidth is the default +% second optional argument determines the rule spacing, \doublerulesep is the default +% usage: \IEEEeqnarraydblrulerow[rule line thickness][rule spacing] +\def\IEEEeqnarraydblrulerowcut{\multispan{\@IEEEeqnnumcols}\relax% span all the cols +% advance column counter only if the IEEEeqnarray environment wants it +\if@advanceIEEEeqncolcnt\global\advance\@IEEEeqncolcnt by \@IEEEeqnnumcols\relax\fi% +\@ifnextchar[{\@IEEEeqnarraydblrulerowcut}{\@IEEEeqnarraydblrulerowcut[\arrayrulewidth]}} +\def\@IEEEeqnarraydblrulerowcut[#1]{\relax\@ifnextchar[{\@@IEEEeqnarraydblrulerowcut[#1]}% +{\@@IEEEeqnarraydblrulerowcut[#1][\doublerulesep]}} +\def\@@IEEEeqnarraydblrulerowcut[#1][#2]{\def\@IEEEeqnarraydblrulerowARG{#1}% +% we allow the user to say \IEEEeqnarraydblrulerow[][] +\ifx\@IEEEeqnarraydblrulerowARG\@empty% +\@IEEEeqnarrayrulerow[\arrayrulewidth]% +\else% +\@IEEEeqnarrayrulerow[#1]% +\fi% +\def\@IEEEeqnarraydblrulerowARG{#2}% +\ifx\@IEEEeqnarraydblrulerowARG\@empty% +\\\IEEEeqnarrayseprowcut[\doublerulesep][\relax]% +\else% +\\\IEEEeqnarrayseprowcut[#2][\relax]% +\fi% +\\\multispan{\@IEEEeqnnumcols}% +% advance column counter only if the IEEEeqnarray environment wants it +\if@advanceIEEEeqncolcnt\global\advance\@IEEEeqncolcnt by \@IEEEeqnnumcols\relax\fi% +\def\@IEEEeqnarraydblrulerowARG{#1}% +\ifx\@IEEEeqnarraydblrulerowARG\@empty% +\@IEEEeqnarrayrulerow[\arrayrulewidth]% +\else% +\@IEEEeqnarrayrulerow[#1]% +\fi% +} + + + +% inserts a full row's worth of &'s +% relies on \@IEEEeqnnumcols to provide the correct number of columns +% uses \@IEEEtrantmptoksA, \count0 as scratch registers +\def\@IEEEeqnarrayhoptolastcolumn{\@IEEEtrantmptoksA={}\count0=1\relax% +\loop% add cols if the user did not use them all +\ifnum\count0<\@IEEEeqnnumcols\relax% +\@IEEEappendtoksA{&}% +\advance\count0 by 1\relax% update the col count +\repeat% +\the\@IEEEtrantmptoksA%execute the &'s +} + + + +\newif\if@IEEEeqnarrayISinner % flag to indicate if we are within the lines +\@IEEEeqnarrayISinnerfalse % of an IEEEeqnarray - after the IEEEeqnarraydecl + +\edef\@IEEEeqnarrayTHEstrutheight{0pt} % height and depth of IEEEeqnarray struts +\edef\@IEEEeqnarrayTHEstrutdepth{0pt} + +\edef\@IEEEeqnarrayTHEmasterstrutheight{0pt} % default height and depth of +\edef\@IEEEeqnarrayTHEmasterstrutdepth{0pt} % struts within an IEEEeqnarray + +\edef\@IEEEeqnarrayTHEmasterstrutHSAVE{0pt} % saved master strut height +\edef\@IEEEeqnarrayTHEmasterstrutDSAVE{0pt} % and depth + +\newif\if@IEEEeqnarrayusemasterstrut % flag to indicate that the master strut value +\@IEEEeqnarrayusemasterstruttrue % is to be used + + + +% saves the strut height and depth of the master strut +\def\@IEEEeqnarraymasterstrutsave{\relax% +\expandafter\skip0=\@IEEEeqnarrayTHEmasterstrutheight\relax% +\expandafter\skip2=\@IEEEeqnarrayTHEmasterstrutdepth\relax% +% remove stretchability +\dimen0\skip0\relax% +\dimen2\skip2\relax% +% save values +\edef\@IEEEeqnarrayTHEmasterstrutHSAVE{\the\dimen0}% +\edef\@IEEEeqnarrayTHEmasterstrutDSAVE{\the\dimen2}} + +% restores the strut height and depth of the master strut +\def\@IEEEeqnarraymasterstrutrestore{\relax% +\expandafter\skip0=\@IEEEeqnarrayTHEmasterstrutHSAVE\relax% +\expandafter\skip2=\@IEEEeqnarrayTHEmasterstrutDSAVE\relax% +% remove stretchability +\dimen0\skip0\relax% +\dimen2\skip2\relax% +% restore values +\edef\@IEEEeqnarrayTHEmasterstrutheight{\the\dimen0}% +\edef\@IEEEeqnarrayTHEmasterstrutdepth{\the\dimen2}} + + +% globally restores the strut height and depth to the +% master values and sets the master strut flag to true +\def\@IEEEeqnarraystrutreset{\relax% +\expandafter\skip0=\@IEEEeqnarrayTHEmasterstrutheight\relax% +\expandafter\skip2=\@IEEEeqnarrayTHEmasterstrutdepth\relax% +% remove stretchability +\dimen0\skip0\relax% +\dimen2\skip2\relax% +% restore values +\xdef\@IEEEeqnarrayTHEstrutheight{\the\dimen0}% +\xdef\@IEEEeqnarrayTHEstrutdepth{\the\dimen2}% +\global\@IEEEeqnarrayusemasterstruttrue} + + +% if the master strut is not to be used, make the current +% values of \@IEEEeqnarrayTHEstrutheight, \@IEEEeqnarrayTHEstrutdepth +% and the use master strut flag, global +% this allows user strut commands issued in the last column to be carried +% into the isolation/strut column +\def\@IEEEeqnarrayglobalizestrutstatus{\relax% +\if@IEEEeqnarrayusemasterstrut\else% +\xdef\@IEEEeqnarrayTHEstrutheight{\@IEEEeqnarrayTHEstrutheight}% +\xdef\@IEEEeqnarrayTHEstrutdepth{\@IEEEeqnarrayTHEstrutdepth}% +\global\@IEEEeqnarrayusemasterstrutfalse% +\fi} + + + +% usage: \IEEEeqnarraystrutsize{height}{depth}[font size commands] +% If called outside the lines of an IEEEeqnarray, sets the height +% and depth of both the master and local struts. If called inside +% an IEEEeqnarray line, sets the height and depth of the local strut +% only and sets the flag to indicate the use of the local strut +% values. If the height or depth is left blank, 0.7\normalbaselineskip +% and 0.3\normalbaselineskip will be used, respectively. +% The optional argument can be used to evaluate the lengths under +% a different font size and styles. If none is specified, the current +% font is used. +% uses scratch registers \skip0, \skip2, \skip3, \dimen0, \dimen2 +\def\IEEEeqnarraystrutsize#1#2{\relax\@ifnextchar[{\@IEEEeqnarraystrutsize{#1}{#2}}{\@IEEEeqnarraystrutsize{#1}{#2}[\relax]}} +\def\@IEEEeqnarraystrutsize#1#2[#3]{\def\@IEEEeqnarraystrutsizeARG{#1}% +\ifx\@IEEEeqnarraystrutsizeARG\@empty% +{\setbox0=\hbox{#3\relax\global\skip3=0.7\normalbaselineskip}}% +\skip0=\skip3\relax% +\else% arg one present +{\setbox0=\hbox{#3\relax\global\skip3=#1\relax}}% +\skip0=\skip3\relax% +\fi% if null arg +\def\@IEEEeqnarraystrutsizeARG{#2}% +\ifx\@IEEEeqnarraystrutsizeARG\@empty% +{\setbox0=\hbox{#3\relax\global\skip3=0.3\normalbaselineskip}}% +\skip2=\skip3\relax% +\else% arg two present +{\setbox0=\hbox{#3\relax\global\skip3=#2\relax}}% +\skip2=\skip3\relax% +\fi% if null arg +% remove stretchability, just to be safe +\dimen0\skip0\relax% +\dimen2\skip2\relax% +% dimen0 = height, dimen2 = depth +\if@IEEEeqnarrayISinner% inner does not touch master strut size +\edef\@IEEEeqnarrayTHEstrutheight{\the\dimen0}% +\edef\@IEEEeqnarrayTHEstrutdepth{\the\dimen2}% +\@IEEEeqnarrayusemasterstrutfalse% do not use master +\else% outer, have to set master strut too +\edef\@IEEEeqnarrayTHEmasterstrutheight{\the\dimen0}% +\edef\@IEEEeqnarrayTHEmasterstrutdepth{\the\dimen2}% +\edef\@IEEEeqnarrayTHEstrutheight{\the\dimen0}% +\edef\@IEEEeqnarrayTHEstrutdepth{\the\dimen2}% +\@IEEEeqnarrayusemasterstruttrue% use master strut +\fi} + + +% usage: \IEEEeqnarraystrutsizeadd{added height}{added depth}[font size commands] +% If called outside the lines of an IEEEeqnarray, adds the given height +% and depth to both the master and local struts. +% If called inside an IEEEeqnarray line, adds the given height and depth +% to the local strut only and sets the flag to indicate the use +% of the local strut values. +% In both cases, if a height or depth is left blank, 0pt is used instead. +% The optional argument can be used to evaluate the lengths under +% a different font size and styles. If none is specified, the current +% font is used. +% uses scratch registers \skip0, \skip2, \skip3, \dimen0, \dimen2 +\def\IEEEeqnarraystrutsizeadd#1#2{\relax\@ifnextchar[{\@IEEEeqnarraystrutsizeadd{#1}{#2}}{\@IEEEeqnarraystrutsizeadd{#1}{#2}[\relax]}} +\def\@IEEEeqnarraystrutsizeadd#1#2[#3]{\def\@IEEEeqnarraystrutsizearg{#1}% +\ifx\@IEEEeqnarraystrutsizearg\@empty% +\skip0=0pt\relax% +\else% arg one present +{\setbox0=\hbox{#3\relax\global\skip3=#1}}% +\skip0=\skip3\relax% +\fi% if null arg +\def\@IEEEeqnarraystrutsizearg{#2}% +\ifx\@IEEEeqnarraystrutsizearg\@empty% +\skip2=0pt\relax% +\else% arg two present +{\setbox0=\hbox{#3\relax\global\skip3=#2}}% +\skip2=\skip3\relax% +\fi% if null arg +% remove stretchability, just to be safe +\dimen0\skip0\relax% +\dimen2\skip2\relax% +% dimen0 = height, dimen2 = depth +\if@IEEEeqnarrayISinner% inner does not touch master strut size +% get local strut size +\expandafter\skip0=\@IEEEeqnarrayTHEstrutheight\relax% +\expandafter\skip2=\@IEEEeqnarrayTHEstrutdepth\relax% +% add it to the user supplied values +\advance\dimen0 by \skip0\relax% +\advance\dimen2 by \skip2\relax% +% update the local strut size +\edef\@IEEEeqnarrayTHEstrutheight{\the\dimen0}% +\edef\@IEEEeqnarrayTHEstrutdepth{\the\dimen2}% +\@IEEEeqnarrayusemasterstrutfalse% do not use master +\else% outer, have to set master strut too +% get master strut size +\expandafter\skip0=\@IEEEeqnarrayTHEmasterstrutheight\relax% +\expandafter\skip2=\@IEEEeqnarrayTHEmasterstrutdepth\relax% +% add it to the user supplied values +\advance\dimen0 by \skip0\relax% +\advance\dimen2 by \skip2\relax% +% update the local and master strut sizes +\edef\@IEEEeqnarrayTHEmasterstrutheight{\the\dimen0}% +\edef\@IEEEeqnarrayTHEmasterstrutdepth{\the\dimen2}% +\edef\@IEEEeqnarrayTHEstrutheight{\the\dimen0}% +\edef\@IEEEeqnarrayTHEstrutdepth{\the\dimen2}% +\@IEEEeqnarrayusemasterstruttrue% use master strut +\fi} + + +% allow user a way to see the struts +\newif\ifIEEEvisiblestruts +\IEEEvisiblestrutsfalse + +% inserts an invisible strut using the master or local strut values +% uses scratch registers \skip0, \skip2, \dimen0, \dimen2 +\def\@IEEEeqnarrayinsertstrut{\relax% +\if@IEEEeqnarrayusemasterstrut +% get master strut size +\expandafter\skip0=\@IEEEeqnarrayTHEmasterstrutheight\relax% +\expandafter\skip2=\@IEEEeqnarrayTHEmasterstrutdepth\relax% +\else% +% get local strut size +\expandafter\skip0=\@IEEEeqnarrayTHEstrutheight\relax% +\expandafter\skip2=\@IEEEeqnarrayTHEstrutdepth\relax% +\fi% +% remove stretchability, probably not needed +\dimen0\skip0\relax% +\dimen2\skip2\relax% +% dimen0 = height, dimen2 = depth +% allow user to see struts if desired +\ifIEEEvisiblestruts% +\vrule width0.2pt height\dimen0 depth\dimen2\relax% +\else% +\vrule width0pt height\dimen0 depth\dimen2\relax\fi} + + +% creates an invisible strut, useable even outside \IEEEeqnarray +% if \IEEEvisiblestrutstrue, the strut will be visible and 0.2pt wide. +% usage: \IEEEstrut[height][depth][font size commands] +% default is \IEEEstrut[0.7\normalbaselineskip][0.3\normalbaselineskip][\relax] +% blank arguments inherit the default values +% uses \dimen0, \dimen2, \skip0, \skip2 +\def\IEEEstrut{\relax\@ifnextchar[{\@IEEEstrut}{\@IEEEstrut[0.7\normalbaselineskip]}} +\def\@IEEEstrut[#1]{\relax\@ifnextchar[{\@@IEEEstrut[#1]}{\@@IEEEstrut[#1][0.3\normalbaselineskip]}} +\def\@@IEEEstrut[#1][#2]{\relax\@ifnextchar[{\@@@IEEEstrut[#1][#2]}{\@@@IEEEstrut[#1][#2][\relax]}} +\def\@@@IEEEstrut[#1][#2][#3]{\mbox{#3\relax% +\def\@IEEEstrutARG{#1}% +\ifx\@IEEEstrutARG\@empty% +\skip0=0.7\normalbaselineskip\relax% +\else% +\skip0=#1\relax% +\fi% +\def\@IEEEstrutARG{#2}% +\ifx\@IEEEstrutARG\@empty% +\skip2=0.3\normalbaselineskip\relax% +\else% +\skip2=#2\relax% +\fi% +% remove stretchability, probably not needed +\dimen0\skip0\relax% +\dimen2\skip2\relax% +\ifIEEEvisiblestruts% +\vrule width0.2pt height\dimen0 depth\dimen2\relax% +\else% +\vrule width0.0pt height\dimen0 depth\dimen2\relax\fi}} + + +% enables strut mode by setting a default strut size and then zeroing the +% \baselineskip, \lineskip, \lineskiplimit and \jot +\def\IEEEeqnarraystrutmode{\IEEEeqnarraystrutsize{0.7\normalbaselineskip}{0.3\normalbaselineskip}[\relax]% +\baselineskip=0pt\lineskip=0pt\lineskiplimit=0pt\jot=0pt} + + +% equation and subequation forms to use to setup hyperref's \@currentHref +\def\@IEEEtheHrefequation{equation.\theHequation} +\def\@IEEEtheHrefsubequation{equation.\theHequation\alph{IEEEsubequation}} + + +\def\IEEEeqnarray{\@IEEEeqnumpersisttrue\@IEEEsubeqnumpersistfalse\@IEEEeqnarray} +\def\endIEEEeqnarray{\end@IEEEeqnarray} + +\@namedef{IEEEeqnarray*}{\@IEEEeqnumpersistfalse\@IEEEsubeqnumpersistfalse\@IEEEeqnarray} +\@namedef{endIEEEeqnarray*}{\end@IEEEeqnarray} + + +% \IEEEeqnarray is an enhanced \eqnarray. +% The star form defaults to not putting equation numbers at the end of each row. +% usage: \IEEEeqnarray[decl]{cols} +\def\@IEEEeqnarray{\relax\@ifnextchar[{\@@IEEEeqnarray}{\@@IEEEeqnarray[\relax]}} +% We have to be careful here to normalize catcodes just before acquiring the +% cols as that specification may contain punctuation which could be subject +% to document catcode changes. +\def\@@IEEEeqnarray[#1]{\begingroup\IEEEnormalcatcodes\@@@IEEEeqnarray[#1]} +\def\@@@IEEEeqnarray[#1]#2{\endgroup + % default to showing the equation number or not based on whether or not + % the star form was involked + \if@IEEEeqnumpersist\global\@eqnswtrue + \else% not the star form + \global\@eqnswfalse + \fi% if star form + % provide a basic hyperref \theHequation if this has not already been setup (hyperref not loaded, or no section counter) + \@ifundefined{theHequation}{\def\theHequation{\arabic{equation}}}{}\relax + % provide dummy hyperref commands in case hyperref is not loaded + \providecommand{\Hy@raisedlink}[1]{}\relax + \providecommand{\hyper@anchorstart}[1]{}\relax + \providecommand{\hyper@anchorend}{}\relax + \providecommand{\@currentHref}{}\relax + \@IEEEeqnumpreadvfalse% reset eqnpreadv flag + \@IEEEsubeqnumpreadvfalse% reset subeqnpreadv flag + \@IEEEeqnarrayISinnerfalse% not yet within the lines of the halign + \@IEEEeqnarraystrutsize{0pt}{0pt}[\relax]% turn off struts by default + \@IEEEeqnarrayusemasterstruttrue% use master strut till user asks otherwise + \IEEEvisiblestrutsfalse% diagnostic mode defaults to off + % no extra space unless the user specifically requests it + \lineskip=0pt\relax + \lineskiplimit=0pt\relax + \baselineskip=\normalbaselineskip\relax% + \jot=\IEEEnormaljot\relax% + \mathsurround\z@\relax% no extra spacing around math + \@advanceIEEEeqncolcnttrue% advance the col counter for each col the user uses, + % used in \IEEEeqnarraymulticol and in the preamble build + %V1.8 Here we preadvance to the next equation number. + % If the user later wants a continued subequation, we can roll back. + \global\@IEEEsubeqnnumrollback=\c@IEEEsubequation% + \stepcounter{equation}\@IEEEeqnumpreadvtrue% advance equation counter before first line + \setcounter{IEEEsubequation}{0}% no subequation yet + \let\@IEEEcurrentlabelsave\@currentlabel% save current label as we later change it globally + \let\@IEEEcurrentHrefsave\@currentHref% save current href label as we later change it globally + \def\@currentlabel{\p@equation\theequation}% redefine the ref label + \def\@currentHref{\@IEEEtheHrefequation}% setup hyperref label + \IEEEeqnarraydecl\relax% allow a way for the user to make global overrides + #1\relax% allow user to override defaults + \let\\\@IEEEeqnarraycr% replace newline with one that can put in eqn. numbers + \global\@IEEEeqncolcnt\z@% col. count = 0 for first line + \@IEEEbuildpreamble{#2}\relax% build the preamble and put it into \@IEEEtrantmptoksA + % put in the column for the equation number + \ifnum\@IEEEeqnnumcols>0\relax\@IEEEappendtoksA{&}\fi% col separator for those after the first + \toks0={##}% + % advance the \@IEEEeqncolcnt for the isolation col, this helps with error checking + \@IEEEappendtoksA{\global\advance\@IEEEeqncolcnt by 1\relax}% + % add the isolation column + \@IEEEappendtoksA{\tabskip\z@skip\bgroup\the\toks0\egroup}% + % advance the \@IEEEeqncolcnt for the equation number col, this helps with error checking + \@IEEEappendtoksA{&\global\advance\@IEEEeqncolcnt by 1\relax}% + % add the equation number col to the preamble + \@IEEEappendtoksA{\tabskip\z@skip\hb@xt@\z@\bgroup\hss\the\toks0\egroup}% + % note \@IEEEeqnnumcols does not count the equation col or isolation col + % set the starting tabskip glue as determined by the preamble build + \tabskip=\@IEEEBPstartglue\relax + % begin the display alignment + \@IEEEeqnarrayISinnertrue% commands are now within the lines + $$\everycr{}\halign to\displaywidth\bgroup + % "exspand" the preamble + \span\the\@IEEEtrantmptoksA\cr} + +% enter isolation/strut column (or the next column if the user did not use +% every column), record the strut status, complete the columns, do the strut if needed, +% restore counters (to backout any equation setup for a next line that was never used) +% to their correct values and exit +\def\end@IEEEeqnarray{\@IEEEeqnarrayglobalizestrutstatus&\@@IEEEeqnarraycr\egroup +\if@IEEEsubeqnumpreadv\global\advance\c@IEEEsubequation\m@ne\fi +\if@IEEEeqnumpreadv\global\advance\c@equation\m@ne\global\c@IEEEsubequation=\@IEEEsubeqnnumrollback\fi +\global\let\@currentlabel\@IEEEcurrentlabelsave% restore current label +\global\let\@currentHref\@IEEEcurrentHrefsave% restore current href label +$$\@ignoretrue} + + +% IEEEeqnarray uses a modifed \\ instead of the plain \cr to +% end rows. This allows for things like \\*[vskip amount] +% These "cr" macros are modified versions of those for LaTeX2e's eqnarray +% the {\ifnum0=`} braces must be kept away from the last column to avoid +% altering spacing of its math, so we use & to advance to the next column +% as there is an isolation/strut column after the user's columns +\def\@IEEEeqnarraycr{\@IEEEeqnarrayglobalizestrutstatus&% save strut status and advance to next column + {\ifnum0=`}\fi + \@ifstar{% + \global\@eqpen\@M\@IEEEeqnarrayYCR + }{% + \global\@eqpen\interdisplaylinepenalty \@IEEEeqnarrayYCR + }% +} + +\def\@IEEEeqnarrayYCR{\@testopt\@IEEEeqnarrayXCR\z@skip} + +\def\@IEEEeqnarrayXCR[#1]{% + \ifnum0=`{\fi}% + \@@IEEEeqnarraycr + \noalign{\penalty\@eqpen\vskip\jot\vskip #1\relax}}% + +\def\@@IEEEeqnarraycr{\@IEEEtrantmptoksA={}% clear token register + \advance\@IEEEeqncolcnt by -1\relax% adjust col count because of the isolation column + \ifnum\@IEEEeqncolcnt>\@IEEEeqnnumcols\relax + \@IEEEclspkgerror{Too many columns within the IEEEeqnarray\MessageBreak + environment}% + {Use fewer \string &'s or put more columns in the IEEEeqnarray column\MessageBreak + specifications.}\relax% + \else + \loop% add cols if the user did not use them all + \ifnum\@IEEEeqncolcnt<\@IEEEeqnnumcols\relax + \@IEEEappendtoksA{&}% + \advance\@IEEEeqncolcnt by 1\relax% update the col count + \repeat + % this number of &'s will take us the the isolation column + \fi + % execute the &'s + \the\@IEEEtrantmptoksA% + % handle the strut/isolation column + \@IEEEeqnarrayinsertstrut% do the strut if needed + \@IEEEeqnarraystrutreset% reset the strut system for next line or IEEEeqnarray + &% and enter the equation number column + \if@eqnsw% only if we display something + \Hy@raisedlink{\hyper@anchorstart{\@currentHref}}% start a hyperref anchor + \global\@IEEEeqnumpreadvfalse\relax% displaying an equation number means + \global\@IEEEsubeqnumpreadvfalse\relax% the equation counters point to valid equations + % V1.8 Here we setup the counters, currentlabel and status for what would be the *next* + % equation line as would be the case under the current settings. However, there are two problems. + % One problem is that there might not ever be a next line. The second problem is that the user + % may later alter the meaning of a line with commands such as \IEEEyessubnumber. So, to handle + % these cases we have to record the current values of the (sub)equation counters and revert back + % to them if the next line is changed or never comes. The \if@IEEEeqnumpreadv, \if@IEEEsubeqnumpreadv + % and \@IEEEsubeqnnumrollback stuff tracks this. + % The logic to handle all this is surprisingly complex, but a nice feature of the approach here is + % that the equation counters and labels remain valid for what the line would be unless a + % \IEEEyessubnumber et al. later changes it. So, any hyperref links are always correct. + \ifnum\c@IEEEsubequation>0\relax% handle subequation + \theIEEEsubequationdis\relax + \if@IEEEsubeqnumpersist% setup for default type of next line + \stepcounter{IEEEsubequation}\global\@IEEEsubeqnumpreadvtrue\relax + \gdef\@currentlabel{\p@IEEEsubequation\theIEEEsubequation}\relax + \gdef\@currentHref{\@IEEEtheHrefsubequation}% setup hyperref label + \else + % if no subeqnum persist, go ahead and setup for a new equation number + \global\@IEEEsubeqnnumrollback=\c@IEEEsubequation + \stepcounter{equation}\global\@IEEEeqnumpreadvtrue\relax + \setcounter{IEEEsubequation}{0}\gdef\@currentlabel{\p@equation\theequation}\relax + \gdef\@currentHref{\@IEEEtheHrefequation}% setup hyperref label + \fi + \else% display a standard equation number + \theequationdis\relax + \setcounter{IEEEsubequation}{0}\relax% not really needed + \if@IEEEsubeqnumpersist% setup for default type of next line + % subequations that follow plain equations carry the same equation number e.g, 5, 5a rather than 5, 6a + \stepcounter{IEEEsubequation}\global\@IEEEsubeqnumpreadvtrue\relax + \gdef\@currentlabel{\p@IEEEsubequation\theIEEEsubequation}\relax + \gdef\@currentHref{\@IEEEtheHrefsubequation}% setup hyperref label + \else + % if no subeqnum persist, go ahead and setup for a new equation number + \global\@IEEEsubeqnnumrollback=\c@IEEEsubequation + \stepcounter{equation}\global\@IEEEeqnumpreadvtrue\relax + \setcounter{IEEEsubequation}{0}\gdef\@currentlabel{\p@equation\theequation}\relax + \gdef\@currentHref{\@IEEEtheHrefequation}% setup hyperref label + \fi + \fi% + \Hy@raisedlink{\hyper@anchorend}% end hyperref anchor + \fi% fi only if we display something + % reset the flags to indicate the default preferences of the display of equation numbers + \if@IEEEeqnumpersist\global\@eqnswtrue\else\global\@eqnswfalse\fi + \if@IEEEsubeqnumpersist\global\@eqnswtrue\fi% ditto for the subequation flag + % reset the number of columns the user actually used + \global\@IEEEeqncolcnt\z@\relax + % the real end of the line + \cr} + + + + + +% \IEEEeqnarraybox is like \IEEEeqnarray except the box form puts everything +% inside a vtop, vbox, or vcenter box depending on the letter in the second +% optional argument (t,b,c). Vbox is the default. Unlike \IEEEeqnarray, +% equation numbers are not displayed and \IEEEeqnarraybox can be nested. +% \IEEEeqnarrayboxm is for math mode (like \array) and does not put the vbox +% within an hbox. +% \IEEEeqnarrayboxt is for text mode (like \tabular) and puts the vbox within +% a \hbox{$ $} construct. +% \IEEEeqnarraybox will auto detect whether to use \IEEEeqnarrayboxm or +% \IEEEeqnarrayboxt depending on the math mode. +% The third optional argument specifies the width this box is to be set to - +% natural width is the default. +% The * forms do not add \jot line spacing +% usage: \IEEEeqnarraybox[decl][pos][width]{cols} +\def\IEEEeqnarrayboxm{\@IEEEeqnarrayboxnojotfalse\@IEEEeqnarrayboxHBOXSWfalse\@IEEEeqnarraybox} +\def\endIEEEeqnarrayboxm{\end@IEEEeqnarraybox} +\@namedef{IEEEeqnarrayboxm*}{\@IEEEeqnarrayboxnojottrue\@IEEEeqnarrayboxHBOXSWfalse\@IEEEeqnarraybox} +\@namedef{endIEEEeqnarrayboxm*}{\end@IEEEeqnarraybox} + +\def\IEEEeqnarrayboxt{\@IEEEeqnarrayboxnojotfalse\@IEEEeqnarrayboxHBOXSWtrue\@IEEEeqnarraybox} +\def\endIEEEeqnarrayboxt{\end@IEEEeqnarraybox} +\@namedef{IEEEeqnarrayboxt*}{\@IEEEeqnarrayboxnojottrue\@IEEEeqnarrayboxHBOXSWtrue\@IEEEeqnarraybox} +\@namedef{endIEEEeqnarrayboxt*}{\end@IEEEeqnarraybox} + +\def\IEEEeqnarraybox{\@IEEEeqnarrayboxnojotfalse\ifmmode\@IEEEeqnarrayboxHBOXSWfalse\else\@IEEEeqnarrayboxHBOXSWtrue\fi% +\@IEEEeqnarraybox} +\def\endIEEEeqnarraybox{\end@IEEEeqnarraybox} + +\@namedef{IEEEeqnarraybox*}{\@IEEEeqnarrayboxnojottrue\ifmmode\@IEEEeqnarrayboxHBOXSWfalse\else\@IEEEeqnarrayboxHBOXSWtrue\fi% +\@IEEEeqnarraybox} +\@namedef{endIEEEeqnarraybox*}{\end@IEEEeqnarraybox} + +% flag to indicate if the \IEEEeqnarraybox needs to put things into an hbox{$ $} +% for \vcenter in non-math mode +\newif\if@IEEEeqnarrayboxHBOXSW% +\@IEEEeqnarrayboxHBOXSWfalse + +\def\@IEEEeqnarraybox{\relax\@ifnextchar[{\@@IEEEeqnarraybox}{\@@IEEEeqnarraybox[\relax]}} +% We have to be careful here to normalize catcodes just before acquiring the +% cols as that specification may contain punctuation which could be subject +% to document catcode changes. +\def\@@IEEEeqnarraybox[#1]{\relax\begingroup\IEEEnormalcatcodes\@ifnextchar[{\@@@IEEEeqnarraybox[#1]}{\@@@IEEEeqnarraybox[#1][b]}} +\def\@@@IEEEeqnarraybox[#1][#2]{\relax\@ifnextchar[{\@@@@IEEEeqnarraybox[#1][#2]}{\@@@@IEEEeqnarraybox[#1][#2][\relax]}} + +% #1 = decl; #2 = t,b,c; #3 = width, #4 = col specs +\def\@@@@IEEEeqnarraybox[#1][#2][#3]#4{\endgroup\@IEEEeqnarrayISinnerfalse % not yet within the lines of the halign + \@IEEEeqnarraymasterstrutsave% save current master strut values + \@IEEEeqnarraystrutsize{0pt}{0pt}[\relax]% turn off struts by default + \@IEEEeqnarrayusemasterstruttrue% use master strut till user asks otherwise + \IEEEvisiblestrutsfalse% diagnostic mode defaults to off + % no extra space unless the user specifically requests it + \lineskip=0pt\relax% + \lineskiplimit=0pt\relax% + \baselineskip=\normalbaselineskip\relax% + \jot=\IEEEnormaljot\relax% + \mathsurround\z@\relax% no extra spacing around math + % the default end glues are zero for an \IEEEeqnarraybox + \edef\@IEEEeqnarraycolSEPdefaultstart{\@IEEEeqnarraycolSEPzero}% default start glue + \edef\@IEEEeqnarraycolSEPdefaultend{\@IEEEeqnarraycolSEPzero}% default end glue + \edef\@IEEEeqnarraycolSEPdefaultmid{\@IEEEeqnarraycolSEPzero}% default inter-column glue + \@advanceIEEEeqncolcntfalse% do not advance the col counter for each col the user uses, + % used in \IEEEeqnarraymulticol and in the preamble build + \IEEEeqnarrayboxdecl\relax% allow a way for the user to make global overrides + #1\relax% allow user to override defaults + \let\\\@IEEEeqnarrayboxcr% replace newline with one that allows optional spacing + \@IEEEbuildpreamble{#4}\relax% build the preamble and put it into \@IEEEtrantmptoksA + % add an isolation column to the preamble to stop \\'s {} from getting into the last col + \ifnum\@IEEEeqnnumcols>0\relax\@IEEEappendtoksA{&}\fi% col separator for those after the first + \toks0={##}% + % add the isolation column to the preamble + \@IEEEappendtoksA{\tabskip\z@skip\bgroup\the\toks0\egroup}% + % set the starting tabskip glue as determined by the preamble build + \tabskip=\@IEEEBPstartglue\relax + % begin the alignment + \everycr{}% + % use only the very first token to determine the positioning + \@IEEEextracttoken{#2}\relax + \ifx\@IEEEextractedtokensdiscarded\@empty\else + \typeout{** WARNING: IEEEeqnarraybox position specifiers after the first in `\@IEEEextracttokenarg' ignored (line \the\inputlineno).}\relax + \fi + % \@IEEEextractedtoken has the first token, the rest are ignored + % if we need to put things into and hbox and go into math mode, do so now + \if@IEEEeqnarrayboxHBOXSW \leavevmode \hbox \bgroup $\fi% + % use the appropriate vbox type + \if\@IEEEextractedtoken t\relax\vtop\else\if\@IEEEextractedtoken c\relax% + \vcenter\else\vbox\fi\fi\bgroup% + \@IEEEeqnarrayISinnertrue% commands are now within the lines + \ifx#3\relax\halign\else\halign to #3\relax\fi% + \bgroup + % "exspand" the preamble + \span\the\@IEEEtrantmptoksA\cr} + +% carry strut status and enter the isolation/strut column, +% exit from math mode if needed, and exit +\def\end@IEEEeqnarraybox{\@IEEEeqnarrayglobalizestrutstatus% carry strut status +&% enter isolation/strut column +\@IEEEeqnarrayinsertstrut% do strut if needed +\@IEEEeqnarraymasterstrutrestore% restore the previous master strut values +% reset the strut system for next IEEEeqnarray +% (sets local strut values back to previous master strut values) +\@IEEEeqnarraystrutreset% +% ensure last line, exit from halign, close vbox +\crcr\egroup\egroup% +% exit from math mode and close hbox if needed +\if@IEEEeqnarrayboxHBOXSW $\egroup\fi} + + + +% IEEEeqnarraybox uses a modifed \\ instead of the plain \cr to +% end rows. This allows for things like \\[vskip amount] +% This "cr" macros are modified versions those for LaTeX2e's eqnarray +% For IEEEeqnarraybox, \\* is the same as \\ +% the {\ifnum0=`} braces must be kept away from the last column to avoid +% altering spacing of its math, so we use & to advance to the isolation/strut column +% carry strut status into isolation/strut column +\def\@IEEEeqnarrayboxcr{\@IEEEeqnarrayglobalizestrutstatus% carry strut status +&% enter isolation/strut column +\@IEEEeqnarrayinsertstrut% do strut if needed +% reset the strut system for next line or IEEEeqnarray +\@IEEEeqnarraystrutreset% +{\ifnum0=`}\fi% +\@ifstar{\@IEEEeqnarrayboxYCR}{\@IEEEeqnarrayboxYCR}} + +% test and setup the optional argument to \\[] +\def\@IEEEeqnarrayboxYCR{\@testopt\@IEEEeqnarrayboxXCR\z@skip} + +% IEEEeqnarraybox does not automatically increase line spacing by \jot +\def\@IEEEeqnarrayboxXCR[#1]{\ifnum0=`{\fi}% +\cr\noalign{\if@IEEEeqnarrayboxnojot\else\vskip\jot\fi\vskip#1\relax}} + + + +% usage: \@IEEEbuildpreamble{column specifiers} +% starts the halign preamble build +% the assembled preamble is put in \@IEEEtrantmptoksA +\def\@IEEEbuildpreamble#1{\@IEEEtrantmptoksA={}% clear token register +\let\@IEEEBPcurtype=u%current column type is not yet known +\let\@IEEEBPprevtype=s%the previous column type was the start +\let\@IEEEBPnexttype=u%next column type is not yet known +% ensure these are valid +\def\@IEEEBPcurglue={0pt plus 0pt minus 0pt}% +\def\@IEEEBPcurcolname{@IEEEdefault}% name of current column definition +% currently acquired numerically referenced glue +% use a name that is easier to remember +\let\@IEEEBPcurnum=\@IEEEtrantmpcountA% +\@IEEEBPcurnum=0% +% tracks number of columns in the preamble +\@IEEEeqnnumcols=0% +% record the default end glues +\edef\@IEEEBPstartglue{\@IEEEeqnarraycolSEPdefaultstart}% +\edef\@IEEEBPendglue{\@IEEEeqnarraycolSEPdefaultend}% +\edef\@IEEEedefMACRO{#1}\relax% fully expand the preamble to support macro containers +% now parse the user's column specifications +% \ignorespaces is used as a delimiter, need at least one trailing \relax because +% \@@IEEEbuildpreamble looks into the future +\expandafter\@@IEEEbuildpreamble\@IEEEedefMACRO\ignorespaces\relax\relax} + + +% usage: \@@IEEEbuildpreamble{current column}{next column} +% parses and builds the halign preamble +\def\@@IEEEbuildpreamble#1#2{\let\@@nextIEEEbuildpreamble=\@@IEEEbuildpreamble% +% use only the very first token to check the end +\@IEEEextracttokengroups{#1}\relax +\ifx\@IEEEextractedfirsttoken\ignorespaces\let\@@nextIEEEbuildpreamble=\@@IEEEfinishpreamble\else% +% identify current and next token type +\@IEEEgetcoltype{#1}{\@IEEEBPcurtype}{1}% current, error on invalid +\@IEEEgetcoltype{#2}{\@IEEEBPnexttype}{0}% next, no error on invalid next +% if curtype is a glue, get the glue def +\if\@IEEEBPcurtype g\@IEEEgetcurglue{#1}{\@IEEEBPcurglue}\fi% +% if curtype is a column, get the column def and set the current column name +\if\@IEEEBPcurtype c\@IEEEgetcurcol{#1}\fi% +% if curtype is a numeral, acquire the user defined glue +\if\@IEEEBPcurtype n\@IEEEprocessNcol{#1}\fi% +% process the acquired glue +\if\@IEEEBPcurtype g\@IEEEprocessGcol\fi% +% process the acquired col +\if\@IEEEBPcurtype c\@IEEEprocessCcol\fi% +% ready prevtype for next col spec. +\let\@IEEEBPprevtype=\@IEEEBPcurtype% +% be sure and put back the future token(s) as a group +\fi\@@nextIEEEbuildpreamble{#2}} + + +% usage: \@@IEEEfinishpreamble{discarded} +% executed just after preamble build is completed +% warn about zero cols, and if prevtype type = u, put in end tabskip glue +% argument is not used +\def\@@IEEEfinishpreamble#1{\ifnum\@IEEEeqnnumcols<1\relax +\@IEEEclspkgerror{No column specifiers declared for IEEEeqnarray}% +{At least one column type must be declared for each IEEEeqnarray.}% +\fi%num cols less than 1 +%if last type undefined, set default end tabskip glue +\if\@IEEEBPprevtype u\@IEEEappendtoksA{\tabskip=\@IEEEBPendglue}\fi} + + +% usage: \@IEEEgetcoltype{col specifier}{\output}{error more} +% Identify and return the column specifier's type code in the given +% \output macro: +% n = number +% g = glue (any other char in catagory 12) +% c = letter +% e = \ignorespaces (end of sequence) +% u = undefined +% error mode: 0 = no error message, 1 = error on invalid char +\def\@IEEEgetcoltype#1#2#3{% +% use only the very first token to determine the type +\@IEEEextracttoken{#1}\relax +% \@IEEEextractedtoken has the first token, the rest are discarded +\let#2=u\relax% assume invalid until know otherwise +\ifx\@IEEEextractedtoken\ignorespaces\let#2=e\else +\ifcat\@IEEEextractedtoken\relax\else% screen out control sequences +\if0\@IEEEextractedtoken\let#2=n\else +\if1\@IEEEextractedtoken\let#2=n\else +\if2\@IEEEextractedtoken\let#2=n\else +\if3\@IEEEextractedtoken\let#2=n\else +\if4\@IEEEextractedtoken\let#2=n\else +\if5\@IEEEextractedtoken\let#2=n\else +\if6\@IEEEextractedtoken\let#2=n\else +\if7\@IEEEextractedtoken\let#2=n\else +\if8\@IEEEextractedtoken\let#2=n\else +\if9\@IEEEextractedtoken\let#2=n\else +\ifcat,\@IEEEextractedtoken\let#2=g\relax +\else\ifcat a\@IEEEextractedtoken\let#2=c\relax\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi +\if#2u\relax +\if0\noexpand#3\relax\else\@IEEEclspkgerror{Invalid character in column specifications}% +{Only letters, numerals and certain other symbols are allowed \MessageBreak +as IEEEeqnarray column specifiers.}\fi\fi} + + +% usage: \@IEEEgetcurcol{col specifier} +% verify the letter referenced column exists +% and return its name in \@IEEEBPcurcolname +% if column specifier is invalid, use the default column @IEEEdefault +\def\@IEEEgetcurcol#1{\expandafter\ifx\csname @IEEEeqnarraycolDEF#1\endcsname\@IEEEeqnarraycolisdefined% +\def\@IEEEBPcurcolname{#1}\else% invalid column name +\@IEEEclspkgerror{Invalid column type "#1" in column specifications.\MessageBreak +Using a default centering column instead}% +{You must define IEEEeqnarray column types before use.}% +\def\@IEEEBPcurcolname{@IEEEdefault}\fi} + + +% usage: \@IEEEgetcurglue{glue specifier}{\output} +% identify the predefined (punctuation) glue value +% and return it in the given output macro +\def\@IEEEgetcurglue#1#2{% +% ! = \! (neg small) -0.16667em (-3/18 em) +% , = \, (small) 0.16667em ( 3/18 em) +% : = \: (med) 0.22222em ( 4/18 em) +% ; = \; (large) 0.27778em ( 5/18 em) +% ' = \quad 1em +% " = \qquad 2em +% . = 0.5\arraycolsep +% / = \arraycolsep +% ? = 2\arraycolsep +% * = 1fil +% + = \@IEEEeqnarraycolSEPcenter +% - = \@IEEEeqnarraycolSEPzero +% Note that all em values are referenced to the math font (textfont2) fontdimen6 +% value for 1em. +% +% use only the very first token to determine the type +\@IEEEextracttoken{#1}\relax +\ifx\@IEEEextractedtokensdiscarded\@empty\else + \typeout{** WARNING: IEEEeqnarray predefined inter-column glue type specifiers after the first in `\@IEEEextracttokenarg' ignored (line \the\inputlineno).}\relax +\fi +% get the math font 1em value +% LaTeX2e's NFSS2 does not preload the fonts, but \IEEEeqnarray needs +% to gain access to the math (\textfont2) font's spacing parameters. +% So we create a bogus box here that uses the math font to ensure +% that \textfont2 is loaded and ready. If this is not done, +% the \textfont2 stuff here may not work. +% Thanks to Bernd Raichle for his 1997 post on this topic. +{\setbox0=\hbox{$\displaystyle\relax$}}% +% fontdimen6 has the width of 1em (a quad). +\@IEEEtrantmpdimenA=\fontdimen6\textfont2\relax% +% identify the glue value based on the first token +% we discard anything after the first +\if!\@IEEEextractedtoken\@IEEEtrantmpdimenA=-0.16667\@IEEEtrantmpdimenA\edef#2{\the\@IEEEtrantmpdimenA}\else +\if,\@IEEEextractedtoken\@IEEEtrantmpdimenA=0.16667\@IEEEtrantmpdimenA\edef#2{\the\@IEEEtrantmpdimenA}\else +\if:\@IEEEextractedtoken\@IEEEtrantmpdimenA=0.22222\@IEEEtrantmpdimenA\edef#2{\the\@IEEEtrantmpdimenA}\else +\if;\@IEEEextractedtoken\@IEEEtrantmpdimenA=0.27778\@IEEEtrantmpdimenA\edef#2{\the\@IEEEtrantmpdimenA}\else +\if'\@IEEEextractedtoken\@IEEEtrantmpdimenA=1\@IEEEtrantmpdimenA\edef#2{\the\@IEEEtrantmpdimenA}\else +\if"\@IEEEextractedtoken\@IEEEtrantmpdimenA=2\@IEEEtrantmpdimenA\edef#2{\the\@IEEEtrantmpdimenA}\else +\if.\@IEEEextractedtoken\@IEEEtrantmpdimenA=0.5\arraycolsep\edef#2{\the\@IEEEtrantmpdimenA}\else +\if/\@IEEEextractedtoken\edef#2{\the\arraycolsep}\else +\if?\@IEEEextractedtoken\@IEEEtrantmpdimenA=2\arraycolsep\edef#2{\the\@IEEEtrantmpdimenA}\else +\if *\@IEEEextractedtoken\edef#2{0pt plus 1fil minus 0pt}\else +\if+\@IEEEextractedtoken\edef#2{\@IEEEeqnarraycolSEPcenter}\else +\if-\@IEEEextractedtoken\edef#2{\@IEEEeqnarraycolSEPzero}\else +\edef#2{\@IEEEeqnarraycolSEPzero}% +\@IEEEclspkgerror{Invalid predefined inter-column glue type "#1" in\MessageBreak +column specifications. Using a default value of\MessageBreak +0pt instead}% +{Only !,:;'"./?*+ and - are valid predefined glue types in the\MessageBreak +IEEEeqnarray column specifications.}\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi} + + +% usage: \@IEEEprocessNcol{digit} +% process a numerical digit from the column specification +% and look up the corresponding user defined glue value +% can transform current type from n to g or a as the user defined glue is acquired +\def\@IEEEprocessNcol#1{\if\@IEEEBPprevtype g% +\@IEEEclspkgerror{Back-to-back inter-column glue specifiers in column\MessageBreak +specifications. Ignoring consecutive glue specifiers\MessageBreak +after the first}% +{You cannot have two or more glue types next to each other\MessageBreak +in the IEEEeqnarray column specifications.}% +\let\@IEEEBPcurtype=a% abort this glue, future digits will be discarded +\@IEEEBPcurnum=0\relax% +\else% if we previously aborted a glue +\if\@IEEEBPprevtype a\@IEEEBPcurnum=0\let\@IEEEBPcurtype=a%maintain digit abortion +\else%acquire this number +% save the previous type before the numerical digits started +\if\@IEEEBPprevtype n\else\let\@IEEEBPprevsavedtype=\@IEEEBPprevtype\fi% +\multiply\@IEEEBPcurnum by 10\relax% +\advance\@IEEEBPcurnum by #1\relax% add in number, \relax is needed to stop TeX's number scan +\if\@IEEEBPnexttype n\else%close acquisition +\expandafter\ifx\csname @IEEEeqnarraycolSEPDEF\expandafter\romannumeral\number\@IEEEBPcurnum\endcsname\@IEEEeqnarraycolisdefined% +\edef\@IEEEBPcurglue{\csname @IEEEeqnarraycolSEP\expandafter\romannumeral\number\@IEEEBPcurnum\endcsname}% +\else%user glue not defined +\@IEEEclspkgerror{Invalid user defined inter-column glue type "\number\@IEEEBPcurnum" in\MessageBreak +column specifications. Using a default value of\MessageBreak +0pt instead}% +{You must define all IEEEeqnarray numerical inter-column glue types via\MessageBreak +\string\IEEEeqnarraydefcolsep \space before they are used in column specifications.}% +\edef\@IEEEBPcurglue{\@IEEEeqnarraycolSEPzero}% +\fi% glue defined or not +\let\@IEEEBPcurtype=g% change the type to reflect the acquired glue +\let\@IEEEBPprevtype=\@IEEEBPprevsavedtype% restore the prev type before this number glue +\@IEEEBPcurnum=0\relax%ready for next acquisition +\fi%close acquisition, get glue +\fi%discard or acquire number +\fi%prevtype glue or not +} + + +% process an acquired glue +% add any acquired column/glue pair to the preamble +\def\@IEEEprocessGcol{\if\@IEEEBPprevtype a\let\@IEEEBPcurtype=a%maintain previous glue abortions +\else +% if this is the start glue, save it, but do nothing else +% as this is not used in the preamble, but before +\if\@IEEEBPprevtype s\edef\@IEEEBPstartglue{\@IEEEBPcurglue}% +\else%not the start glue +\if\@IEEEBPprevtype g%ignore if back to back glues +\@IEEEclspkgerror{Back-to-back inter-column glue specifiers in column\MessageBreak +specifications. Ignoring consecutive glue specifiers\MessageBreak +after the first}% +{You cannot have two or more glue types next to each other\MessageBreak +in the IEEEeqnarray column specifications.}% +\let\@IEEEBPcurtype=a% abort this glue +\else% not a back to back glue +\if\@IEEEBPprevtype c\relax% if the previoustype was a col, add column/glue pair to preamble +\ifnum\@IEEEeqnnumcols>0\relax\@IEEEappendtoksA{&}\fi +\toks0={##}% +% make preamble advance col counter if this environment needs this +\if@advanceIEEEeqncolcnt\@IEEEappendtoksA{\global\advance\@IEEEeqncolcnt by 1\relax}\fi +% insert the column defintion into the preamble, being careful not to expand +% the column definition +\@IEEEappendtoksA{\tabskip=\@IEEEBPcurglue}% +\@IEEEappendNOEXPANDtoksA{\begingroup\csname @IEEEeqnarraycolPRE}% +\@IEEEappendtoksA{\@IEEEBPcurcolname}% +\@IEEEappendNOEXPANDtoksA{\endcsname}% +\@IEEEappendtoksA{\the\toks0}% +\@IEEEappendNOEXPANDtoksA{\relax\relax\relax\relax\relax% +\relax\relax\relax\relax\relax\csname @IEEEeqnarraycolPOST}% +\@IEEEappendtoksA{\@IEEEBPcurcolname}% +\@IEEEappendNOEXPANDtoksA{\endcsname\relax\relax\relax\relax\relax% +\relax\relax\relax\relax\relax\endgroup}% +\advance\@IEEEeqnnumcols by 1\relax%one more column in the preamble +\else% error: non-start glue with no pending column +\@IEEEclspkgerror{Inter-column glue specifier without a prior column\MessageBreak +type in the column specifications. Ignoring this glue\MessageBreak +specifier}% +{Except for the first and last positions, glue can be placed only\MessageBreak +between column types.}% +\let\@IEEEBPcurtype=a% abort this glue +\fi% previous was a column +\fi% back-to-back glues +\fi% is start column glue +\fi% prev type not a +} + + +% process an acquired letter referenced column and, if necessary, add it to the preamble +\def\@IEEEprocessCcol{\if\@IEEEBPnexttype g\else +\if\@IEEEBPnexttype n\else +% we have a column followed by something other than a glue (or numeral glue) +% so we must add this column to the preamble now +\ifnum\@IEEEeqnnumcols>0\relax\@IEEEappendtoksA{&}\fi%col separator for those after the first +\if\@IEEEBPnexttype e\@IEEEappendtoksA{\tabskip=\@IEEEBPendglue\relax}\else%put in end glue +\@IEEEappendtoksA{\tabskip=\@IEEEeqnarraycolSEPdefaultmid\relax}\fi% or default mid glue +\toks0={##}% +% make preamble advance col counter if this environment needs this +\if@advanceIEEEeqncolcnt\@IEEEappendtoksA{\global\advance\@IEEEeqncolcnt by 1\relax}\fi +% insert the column definition into the preamble, being careful not to expand +% the column definition +\@IEEEappendNOEXPANDtoksA{\begingroup\csname @IEEEeqnarraycolPRE}% +\@IEEEappendtoksA{\@IEEEBPcurcolname}% +\@IEEEappendNOEXPANDtoksA{\endcsname}% +\@IEEEappendtoksA{\the\toks0}% +\@IEEEappendNOEXPANDtoksA{\relax\relax\relax\relax\relax% +\relax\relax\relax\relax\relax\csname @IEEEeqnarraycolPOST}% +\@IEEEappendtoksA{\@IEEEBPcurcolname}% +\@IEEEappendNOEXPANDtoksA{\endcsname\relax\relax\relax\relax\relax% +\relax\relax\relax\relax\relax\endgroup}% +\advance\@IEEEeqnnumcols by 1\relax%one more column in the preamble +\fi%next type not numeral +\fi%next type not glue +} + + +%% +%% END OF IEEEeqnarray DEFINITIONS +%% + + + + + +% set up the running headers and footers +% +% header and footer font and size specifications +\def\@IEEEheaderstyle{\normalfont\scriptsize} +\def\@IEEEfooterstyle{\normalfont\scriptsize} +% +% compsoc uses sans-serif headers and footers +\ifCLASSOPTIONcompsoc + \def\@IEEEheaderstyle{\normalfont\sffamily\scriptsize} + \def\@IEEEfooterstyle{\normalfont\sffamily\scriptsize} +\fi + + +% standard page style, ps@headings +\def\ps@headings{% default to standard twoside headers, no footers +% will change later if the mode requires otherwise +\def\@oddhead{\hbox{}\@IEEEheaderstyle\rightmark\hfil\thepage}\relax +\def\@evenhead{\@IEEEheaderstyle\thepage\hfil\leftmark\hbox{}}\relax +\let\@oddfoot\@empty +\let\@evenfoot\@empty +\ifCLASSOPTIONtechnote + % technote twoside + \def\@oddhead{\hbox{}\@IEEEheaderstyle\leftmark\hfil\thepage}\relax + \def\@evenhead{\@IEEEheaderstyle\thepage\hfil\leftmark\hbox{}}\relax +\fi +\ifCLASSOPTIONdraftcls + % draft footers + \def\@oddfoot{\@IEEEfooterstyle\@date\hfil DRAFT}\relax + \def\@evenfoot{\@IEEEfooterstyle DRAFT\hfil\@date}\relax +\fi +% oneside +\if@twoside\else + % standard one side headers + \def\@oddhead{\hbox{}\@IEEEheaderstyle\leftmark\hfil\thepage}\relax + \let\@evenhead\@empty + \ifCLASSOPTIONdraftcls + % oneside draft footers + \def\@oddfoot{\@IEEEfooterstyle\@date\hfil DRAFT}\relax + \let\@evenfoot\@empty + \fi +\fi +% turn off headers for conferences +\ifCLASSOPTIONconference + \let\@oddhead\@empty + \let\@evenhead\@empty +\fi +% turn off footers for draftclsnofoot +\ifCLASSOPTIONdraftclsnofoot + \let\@oddfoot\@empty + \let\@evenfoot\@empty +\fi} + + +% title page style, ps@IEEEtitlepagestyle +\def\ps@IEEEtitlepagestyle{% default title page headers, no footers +\def\@oddhead{\hbox{}\@IEEEheaderstyle\leftmark\hfil\thepage}\relax +\def\@evenhead{\@IEEEheaderstyle\thepage\hfil\leftmark\hbox{}}\relax +\let\@oddfoot\@empty +\let\@evenfoot\@empty +% will change later if the mode requires otherwise +\ifCLASSOPTIONdraftcls + % draft footers + \ifCLASSOPTIONdraftclsnofoot\else + % but only if not draftclsnofoot + \def\@oddfoot{\@IEEEfooterstyle\@date\hfil DRAFT}\relax + \def\@evenfoot{\@IEEEfooterstyle DRAFT\hfil\@date}\relax + \fi +\else + % all nondraft mode footers + \if@IEEEusingpubid + % for title pages that are using a pubid + % do not repeat pubid on the title page if using a peer review cover page + \ifCLASSOPTIONpeerreview\else + % for noncompsoc papers, the pubid uses footnotesize and + % is at the same vertical position as where the last baseline would normally be + \def\@oddfoot{\hbox{}\hss\@IEEEfooterstyle\footnotesize\raisebox{\footskip}[0pt][0pt]{\@IEEEpubid}\hss\hbox{}}\relax + \def\@evenfoot{\hbox{}\hss\@IEEEfooterstyle\footnotesize\raisebox{\footskip}[0pt][0pt]{\@IEEEpubid}\hss\hbox{}}\relax + \ifCLASSOPTIONcompsoc + % for compsoc papers, the pubid is at the same vertical position as the normal footer + \def\@oddfoot{\hbox{}\hss\@IEEEfooterstyle\raisebox{0pt}[0pt][0pt]{\@IEEEpubid}\hss\hbox{}}\relax + \def\@evenfoot{\hbox{}\hss\@IEEEfooterstyle\raisebox{0pt}[0pt][0pt]{\@IEEEpubid}\hss\hbox{}}\relax + \fi + \fi + \fi +\fi +% turn off headers for conferences +\ifCLASSOPTIONconference + \let\@oddhead\@empty + \let\@evenhead\@empty +\fi} + + +% peer review cover page style, ps@IEEEpeerreviewcoverpagestyle +\def\ps@IEEEpeerreviewcoverpagestyle{% default peer review cover no headers, no footers +\let\@oddhead\@empty +\let\@evenhead\@empty +\let\@oddfoot\@empty +\let\@evenfoot\@empty +% will change later if the mode requires otherwise +\ifCLASSOPTIONdraftcls + % draft footers + \ifCLASSOPTIONdraftclsnofoot\else + % but only if not draftclsnofoot + \def\@oddfoot{\@IEEEfooterstyle\@date\hfil DRAFT}\relax + \def\@evenfoot{\@IEEEfooterstyle DRAFT\hfil\@date}\relax + \fi +\else + % all nondraft mode footers + \if@IEEEusingpubid + % for peer review cover pages that are using a pubid + % for noncompsoc papers, the pubid uses footnotesize and + % is at the same vertical position as where the last baseline would normally be + \def\@oddfoot{\hbox{}\hss\@IEEEfooterstyle\footnotesize\raisebox{\footskip}[0pt][0pt]{\@IEEEpubid}\hss\hbox{}}\relax + \def\@evenfoot{\hbox{}\hss\@IEEEfooterstyle\footnotesize\raisebox{\footskip}[0pt][0pt]{\@IEEEpubid}\hss\hbox{}}\relax + \ifCLASSOPTIONcompsoc + % for compsoc papers, the pubid is at the same vertical position as the normal footer + \def\@oddfoot{\hbox{}\hss\@IEEEfooterstyle\raisebox{0pt}[0pt][0pt]{\@IEEEpubid}\hss\hbox{}}\relax + \def\@evenfoot{\hbox{}\hss\@IEEEfooterstyle\raisebox{0pt}[0pt][0pt]{\@IEEEpubid}\hss\hbox{}}\relax + \fi + \fi +\fi} + + + +%% Defines the command for putting the header. +%% Note that all the text is forced into uppercase, if you have some text +%% that needs to be in lower case, for instance et. al., then either manually +%% set \leftmark and \rightmark or use \MakeLowercase{et. al.} within the +%% arguments to \markboth. +%% V1.7b add \protect to work with Babel +\def\markboth#1#2{\def\leftmark{\MakeUppercase{\protect#1}}% +\def\rightmark{\MakeUppercase{\protect#2}}} + +\def\today{\ifcase\month\or + January\or February\or March\or April\or May\or June\or + July\or August\or September\or October\or November\or December\fi + \space\number\day, \number\year} + + + + +%% CITATION AND BIBLIOGRAPHY COMMANDS +%% +%% V1.6 no longer supports the older, nonstandard \shortcite and \citename setup stuff +% +% +% Modify Latex2e \@citex to separate citations with "], [" +\def\@citex[#1]#2{% + \let\@citea\@empty + \@cite{\@for\@citeb:=#2\do + {\@citea\def\@citea{], [}% + \edef\@citeb{\expandafter\@firstofone\@citeb\@empty}% + \if@filesw\immediate\write\@auxout{\string\citation{\@citeb}}\fi + \@ifundefined{b@\@citeb}{\mbox{\reset@font\bfseries ?}% + \G@refundefinedtrue + \@latex@warning + {Citation `\@citeb' on page \thepage \space undefined}}% + {\hbox{\csname b@\@citeb\endcsname}}}}{#1}} + +% V1.6 we create hooks for the optional use of Donald Arseneau's +% cite.sty package. cite.sty is "smart" and will notice that the +% following format controls are already defined and will not +% redefine them. The result will be the proper sorting of the +% citation numbers and auto detection of 3 or more entry "ranges" - +% all in IEEE style: [1], [2], [5]--[7], [12] +% This also allows for an optional note, i.e., \cite[mynote]{..}. +% If the \cite with note has more than one reference, the note will +% be applied to the last of the listed references. It is generally +% desired that if a note is given, only one reference is listed in +% that \cite. +% Thanks to Mr. Arseneau for providing the required format arguments +% to produce the IEEE style. +\def\citepunct{], [} +\def\citedash{]--[} + +% V1.7 default to using same font for urls made by url.sty +\AtBeginDocument{\csname url@samestyle\endcsname} + +% V1.6 class files should always provide these +\def\newblock{\hskip .11em\@plus.33em\@minus.07em} +\let\@openbib@code\@empty +% V1.8b article.cls is now providing these too +% we do not use \@mkboth, nor alter the page style +\newenvironment{theindex} + {\if@twocolumn + \@restonecolfalse + \else + \@restonecoltrue + \fi + \twocolumn[\section*{\indexname}]% + \parindent\z@ + \parskip\z@ \@plus .3\p@\relax + \columnseprule \z@ + \columnsep 35\p@ + \let\item\@idxitem} + {\if@restonecol\onecolumn\else\clearpage\fi} +\newcommand\@idxitem{\par\hangindent 40\p@} +\newcommand\subitem{\@idxitem \hspace*{20\p@}} +\newcommand\subsubitem{\@idxitem \hspace*{30\p@}} +\newcommand\indexspace{\par \vskip 10\p@ \@plus5\p@ \@minus3\p@\relax} + + + +% Provide support for the control entries of IEEEtran.bst V1.00 and later. +% V1.7 optional argument allows for a different aux file to be specified in +% order to handle multiple bibliographies. For example, with multibib.sty: +% \newcites{sec}{Secondary Literature} +% \bstctlcite[@auxoutsec]{BSTcontrolhak} +\def\bstctlcite{\@ifnextchar[{\@bstctlcite}{\@bstctlcite[@auxout]}} +\def\@bstctlcite[#1]#2{\@bsphack + \@for\@citeb:=#2\do{% + \edef\@citeb{\expandafter\@firstofone\@citeb}% + \if@filesw\immediate\write\csname #1\endcsname{\string\citation{\@citeb}}\fi}% + \@esphack} + +% \IEEEnoauxwrite{} allows for citations that do not add to or affect +% the order of the existing citation list. Can be useful for \cite +% within \thanks{}. +\DeclareRobustCommand{\IEEEnoauxwrite}[1]{\relax +\if@filesw +\@fileswfalse +#1\relax\relax\relax\relax\relax +\@fileswtrue +\else +#1\relax\relax\relax\relax\relax +\fi} + +% V1.6 provide a way for a user to execute a command just before +% a given reference number - used to insert a \newpage to balance +% the columns on the last page +\edef\@IEEEtriggerrefnum{0} % the default of zero means that + % the command is not executed +\def\@IEEEtriggercmd{\newpage} + +% allow the user to alter the triggered command +\long\def\IEEEtriggercmd#1{\long\def\@IEEEtriggercmd{#1}} + +% allow user a way to specify the reference number just before the +% command is executed +\def\IEEEtriggeratref#1{\@IEEEtrantmpcountA=#1% +\edef\@IEEEtriggerrefnum{\the\@IEEEtrantmpcountA}}% + +% trigger command at the given reference +\def\@IEEEbibitemprefix{\@IEEEtrantmpcountA=\@IEEEtriggerrefnum\relax% +\advance\@IEEEtrantmpcountA by -1\relax% +\ifnum\c@enumiv=\@IEEEtrantmpcountA\relax\@IEEEtriggercmd\relax\fi} + + +\def\@biblabel#1{[#1]} + +% compsoc journals and conferences left align the reference numbers +\@IEEEcompsoconly{\def\@biblabel#1{[#1]\hfill}} + +% controls bib item spacing +\def\IEEEbibitemsep{0pt plus .5pt} + +\@IEEEcompsocconfonly{\def\IEEEbibitemsep{0.5\baselineskip plus 0.25\baselineskip minus 0.25\baselineskip}} + + +\def\thebibliography#1{\section*{\refname}% + \addcontentsline{toc}{section}{\refname}% + % V1.6 add some rubber space here and provide a command trigger + \footnotesize\vskip 0.3\baselineskip plus 0.1\baselineskip minus 0.1\baselineskip% + \list{\@biblabel{\@arabic\c@enumiv}}% + {\settowidth\labelwidth{\@biblabel{#1}}% + \leftmargin\labelwidth + \advance\leftmargin\labelsep\relax + \itemsep \IEEEbibitemsep\relax + \usecounter{enumiv}% + \let\p@enumiv\@empty + \renewcommand\theenumiv{\@arabic\c@enumiv}}% + \let\@IEEElatexbibitem\bibitem% + \def\bibitem{\@IEEEbibitemprefix\@IEEElatexbibitem}% +\def\newblock{\hskip .11em plus .33em minus .07em}% +% originally: +% \sloppy\clubpenalty4000\widowpenalty4000% +% by adding the \interlinepenalty here, we make it more +% difficult, but not impossible, for LaTeX to break within a reference. +% The IEEE almost never breaks a reference (but they do it more often with +% technotes). You may get an underfull vbox warning around the bibliography, +% but the final result will be much more like what the IEEE will publish. +% MDS 11/2000 +\ifCLASSOPTIONtechnote\sloppy\clubpenalty4000\widowpenalty4000\interlinepenalty100% +\else\sloppy\clubpenalty4000\widowpenalty4000\interlinepenalty500\fi% + \sfcode`\.=1000\relax} +\let\endthebibliography=\endlist + + + + +% TITLE PAGE COMMANDS +% +% +% \IEEEmembership is used to produce the sublargesize italic font used to indicate author +% IEEE membership. compsoc uses a large size sans slant font +\def\IEEEmembership#1{{\@IEEEnotcompsoconly{\sublargesize}\normalfont\@IEEEcompsoconly{\sffamily}\textit{#1}}} + + +% \IEEEauthorrefmark{} produces a footnote type symbol to indicate author affiliation. +% When given an argument of 1 to 9, \IEEEauthorrefmark{} follows the standard LaTeX footnote +% symbol sequence convention. However, for arguments 10 and above, \IEEEauthorrefmark{} +% reverts to using lower case roman numerals, so it cannot overflow. Do note that you +% cannot use \footnotemark[] in place of \IEEEauthorrefmark{} within \author as the footnote +% symbols will have been turned off to prevent \thanks from creating footnote marks. +% \IEEEauthorrefmark{} produces a symbol that appears to LaTeX as having zero vertical +% height - this allows for a more compact line packing, but the user must ensure that +% the interline spacing is large enough to prevent \IEEEauthorrefmark{} from colliding +% with the text above. +% V1.7 make this a robust command +% V1.8 transmag uses an arabic author affiliation symbol +\ifCLASSOPTIONtransmag +\DeclareRobustCommand*{\IEEEauthorrefmark}[1]{\raisebox{0pt}[0pt][0pt]{\textsuperscript{\footnotesize #1}}} +\else +\DeclareRobustCommand*{\IEEEauthorrefmark}[1]{\raisebox{0pt}[0pt][0pt]{\textsuperscript{\footnotesize\ensuremath{\ifcase#1\or *\or \dagger\or \ddagger\or% + \mathsection\or \mathparagraph\or \|\or **\or \dagger\dagger% + \or \ddagger\ddagger \else\textsuperscript{\expandafter\romannumeral#1}\fi}}}} +\fi + + +% FONT CONTROLS AND SPACINGS FOR CONFERENCE MODE AUTHOR NAME AND AFFILIATION BLOCKS +% +% The default font styles for the author name and affiliation blocks (confmode) +\def\@IEEEauthorblockNstyle{\normalfont\@IEEEcompsocnotconfonly{\sffamily}\sublargesize} +\def\@IEEEauthorblockAstyle{\normalfont\@IEEEcompsocnotconfonly{\sffamily}\@IEEEcompsocconfonly{\itshape}\normalsize} +% The default if the user does not use an author block +\def\@IEEEauthordefaulttextstyle{\normalfont\@IEEEcompsocnotconfonly{\sffamily}\sublargesize} + +% adjustment spacing from title (or special paper notice) to author name blocks (confmode) +% can be negative +\def\@IEEEauthorblockconfadjspace{-0.25em} +% compsoc conferences need more space here +\@IEEEcompsocconfonly{\def\@IEEEauthorblockconfadjspace{0.75\@IEEEnormalsizeunitybaselineskip}} + +% spacing between name and affiliation blocks (confmode) +% This can be negative. +% The IEEE doesn't want any added spacing here, but I will leave these +% controls in place in case they ever change their mind. +% Personally, I like 0.75ex. +%\def\@IEEEauthorblockNtopspace{0.75ex} +%\def\@IEEEauthorblockAtopspace{0.75ex} +\def\@IEEEauthorblockNtopspace{0.0ex} +\def\@IEEEauthorblockAtopspace{0.0ex} +\ifCLASSOPTIONtransmag +% transmag uses one line of space above first affiliation block +\def\@IEEEauthorblockAtopspace{1\@IEEEnormalsizeunitybaselineskip} +\fi + +% baseline spacing within name and affiliation blocks (confmode) +% must be positive, spacings below certain values will make +% the position of line of text sensitive to the contents of the +% line above it i.e., whether or not the prior line has descenders, +% subscripts, etc. For this reason it is a good idea to keep +% these above 2.6ex +\def\@IEEEauthorblockNinterlinespace{2.6ex} +\def\@IEEEauthorblockAinterlinespace{2.75ex} + +% This tracks the required strut size. +% See the \@IEEEauthorhalign command for the actual default value used. +\def\@IEEEauthorblockXinterlinespace{2.7ex} + +% variables to retain font size and style across groups +% values given here have no effect as they will be overwritten later +\gdef\@IEEESAVESTATEfontsize{10} +\gdef\@IEEESAVESTATEfontbaselineskip{12} +\gdef\@IEEESAVESTATEfontencoding{OT1} +\gdef\@IEEESAVESTATEfontfamily{ptm} +\gdef\@IEEESAVESTATEfontseries{m} +\gdef\@IEEESAVESTATEfontshape{n} + +% saves the current font attributes +\def\@IEEEcurfontSAVE{\global\let\@IEEESAVESTATEfontsize\f@size% +\global\let\@IEEESAVESTATEfontbaselineskip\f@baselineskip% +\global\let\@IEEESAVESTATEfontencoding\f@encoding% +\global\let\@IEEESAVESTATEfontfamily\f@family% +\global\let\@IEEESAVESTATEfontseries\f@series% +\global\let\@IEEESAVESTATEfontshape\f@shape} + +% restores the saved font attributes +\def\@IEEEcurfontRESTORE{\fontsize{\@IEEESAVESTATEfontsize}{\@IEEESAVESTATEfontbaselineskip}% +\fontencoding{\@IEEESAVESTATEfontencoding}% +\fontfamily{\@IEEESAVESTATEfontfamily}% +\fontseries{\@IEEESAVESTATEfontseries}% +\fontshape{\@IEEESAVESTATEfontshape}% +\selectfont} + + +% variable to indicate if the current block is the first block in the column +\newif\if@IEEEprevauthorblockincol \@IEEEprevauthorblockincolfalse + + +% the command places a strut with height and depth = \@IEEEauthorblockXinterlinespace +% we use this technique to have complete manual control over the spacing of the lines +% within the halign environment. +% We set the below baseline portion at 30%, the above +% baseline portion at 70% of the total length. +% Responds to changes in the document's \baselinestretch +\def\@IEEEauthorstrutrule{\@IEEEtrantmpdimenA\@IEEEauthorblockXinterlinespace% +\@IEEEtrantmpdimenA=\baselinestretch\@IEEEtrantmpdimenA% +\rule[-0.3\@IEEEtrantmpdimenA]{0pt}{\@IEEEtrantmpdimenA}} + + +% blocks to hold the authors' names and affilations. +% Makes formatting easy for conferences +% +% use real definitions in conference mode +% name block +\def\IEEEauthorblockN#1{\relax\@IEEEauthorblockNstyle% set the default text style +\gdef\@IEEEauthorblockXinterlinespace{0pt}% disable strut for spacer row +% the \expandafter hides the \cr in conditional tex, see the array.sty docs +% for details, probably not needed here as the \cr is in a macro +% do a spacer row if needed +\if@IEEEprevauthorblockincol\expandafter\@IEEEauthorblockNtopspaceline\fi +\global\@IEEEprevauthorblockincoltrue% we now have a block in this column +%restore the correct strut value +\gdef\@IEEEauthorblockXinterlinespace{\@IEEEauthorblockNinterlinespace}% +% input the author names +#1% +% end the row if the user did not already +\crcr} +% spacer row for names +\def\@IEEEauthorblockNtopspaceline{\cr\noalign{\vskip\@IEEEauthorblockNtopspace}} +% +% affiliation block +\def\IEEEauthorblockA#1{\relax\@IEEEauthorblockAstyle% set the default text style +\gdef\@IEEEauthorblockXinterlinespace{0pt}%disable strut for spacer row +% the \expandafter hides the \cr in conditional tex, see the array.sty docs +% for details, probably not needed here as the \cr is in a macro +% do a spacer row if needed +\if@IEEEprevauthorblockincol\expandafter\@IEEEauthorblockAtopspaceline\fi +\global\@IEEEprevauthorblockincoltrue% we now have a block in this column +%restore the correct strut value +\gdef\@IEEEauthorblockXinterlinespace{\@IEEEauthorblockAinterlinespace}% +% input the author affiliations +#1% +% end the row if the user did not already +\crcr +% V1.8 transmag does not use any additional affiliation spacing after the first author +\ifCLASSOPTIONtransmag\gdef\@IEEEauthorblockAtopspace{0pt}\fi} + +% spacer row for affiliations +\def\@IEEEauthorblockAtopspaceline{\cr\noalign{\vskip\@IEEEauthorblockAtopspace}} + + +% allow papers to compile even if author blocks are used in modes other +% than conference or peerreviewca. For such cases, we provide dummy blocks. +\ifCLASSOPTIONconference +\else + \ifCLASSOPTIONpeerreviewca\else + % not conference, peerreviewca or transmag mode + \ifCLASSOPTIONtransmag\else + \def\IEEEauthorblockN#1{#1}% + \def\IEEEauthorblockA#1{#1}% + \fi + \fi +\fi + + + +% we provide our own halign so as not to have to depend on tabular +\def\@IEEEauthorhalign{\@IEEEauthordefaulttextstyle% default text style + \lineskip=0pt\relax% disable line spacing + \lineskiplimit=0pt\relax% + \baselineskip=0pt\relax% + \@IEEEcurfontSAVE% save the current font + \mathsurround\z@\relax% no extra spacing around math + \let\\\@IEEEauthorhaligncr% replace newline with halign friendly one + \tabskip=0pt\relax% no column spacing + \everycr{}% ensure no problems here + \@IEEEprevauthorblockincolfalse% no author blocks yet + \def\@IEEEauthorblockXinterlinespace{2.7ex}% default interline space + \vtop\bgroup%vtop box + \halign\bgroup&\relax\hfil\@IEEEcurfontRESTORE\relax ##\relax + \hfil\@IEEEcurfontSAVE\@IEEEauthorstrutrule\cr} + +% ensure last line, exit from halign, close vbox +\def\end@IEEEauthorhalign{\crcr\egroup\egroup} + +% handle bogus star form +\def\@IEEEauthorhaligncr{{\ifnum0=`}\fi\@ifstar{\@@IEEEauthorhaligncr}{\@@IEEEauthorhaligncr}} + +% test and setup the optional argument to \\[] +\def\@@IEEEauthorhaligncr{\@testopt\@@@IEEEauthorhaligncr\z@skip} + +% end the line and do the optional spacer +\def\@@@IEEEauthorhaligncr[#1]{\ifnum0=`{\fi}\cr\noalign{\vskip#1\relax}} + + + +% flag to prevent multiple \and warning messages +\newif\if@IEEEWARNand +\@IEEEWARNandtrue + +% if in conference or peerreviewca modes, we support the use of \and as \author is a +% tabular environment, otherwise we warn the user that \and is invalid +% outside of conference or peerreviewca modes. +\def\and{\relax} % provide a bogus \and that we will then override + +\renewcommand{\and}[1][\relax]{\if@IEEEWARNand\typeout{** WARNING: \noexpand\and is valid only + when in conference or peerreviewca}\typeout{modes (line \the\inputlineno).}\fi\global\@IEEEWARNandfalse} + +\ifCLASSOPTIONconference% +\renewcommand{\and}[1][\hfill]{\end{@IEEEauthorhalign}#1\begin{@IEEEauthorhalign}}% +\fi +\ifCLASSOPTIONpeerreviewca +\renewcommand{\and}[1][\hfill]{\end{@IEEEauthorhalign}#1\begin{@IEEEauthorhalign}}% +\fi +% V1.8 transmag uses conference author format +\ifCLASSOPTIONtransmag +\renewcommand{\and}[1][\hfill]{\end{@IEEEauthorhalign}#1\begin{@IEEEauthorhalign}}% +\fi + +% page clearing command +% based on LaTeX2e's \cleardoublepage, but allows different page styles +% for the inserted blank pages +\def\@IEEEcleardoublepage#1{\clearpage\if@twoside\ifodd\c@page\else +\hbox{}\thispagestyle{#1}\newpage\if@twocolumn\hbox{}\thispagestyle{#1}\newpage\fi\fi\fi} + +% V1.8b hooks to allow adjustment of space above title +\def\IEEEtitletopspace{0.5\baselineskip} +% an added extra amount to allow for adjustment/offset +\def\IEEEtitletopspaceextra{0pt} + +% user command to invoke the title page +\def\maketitle{\par% + \begingroup% + \normalfont% + \def\thefootnote{}% the \thanks{} mark type is empty + \def\footnotemark{}% and kill space from \thanks within author + \let\@makefnmark\relax% V1.7, must *really* kill footnotemark to remove all \textsuperscript spacing as well. + \footnotesize% equal spacing between thanks lines + \footnotesep 0.7\baselineskip%see global setting of \footnotesep for more info + % V1.7 disable \thanks note indention for compsoc + \@IEEEcompsoconly{\long\def\@makefntext##1{\parindent 1em\noindent\hbox{\@makefnmark}##1}}% + \normalsize% + \ifCLASSOPTIONpeerreview + \newpage\global\@topnum\z@ \@maketitle\@IEEEstatictitlevskip\@IEEEaftertitletext% + \thispagestyle{IEEEpeerreviewcoverpagestyle}\@thanks% + \else + \if@twocolumn% + \ifCLASSOPTIONtechnote% + \newpage\global\@topnum\z@ \@maketitle\@IEEEstatictitlevskip\@IEEEaftertitletext% + \else + \twocolumn[{\IEEEquantizevspace{\@maketitle}[\IEEEquantizedisabletitlecmds]{0pt}[-\topskip]{\baselineskip}{\@IEEENORMtitlevspace}{\@IEEEMINtitlevspace}\@IEEEaftertitletext}]% + \fi + \else + \newpage\global\@topnum\z@ \@maketitle\@IEEEstatictitlevskip\@IEEEaftertitletext% + \fi + \thispagestyle{IEEEtitlepagestyle}\@thanks% + \fi + % pullup page for pubid if used. + \if@IEEEusingpubid + \enlargethispage{-\@IEEEpubidpullup}% + \fi + \endgroup + \setcounter{footnote}{0}\let\maketitle\relax\let\@maketitle\relax + \gdef\@thanks{}% + % v1.6b do not clear these as we will need the title again for peer review papers + % \gdef\@author{}\gdef\@title{}% + \let\thanks\relax} + + +% V1.8 parbox to format \@IEEEtitleabstractindextext +\long\def\@IEEEtitleabstractindextextbox#1{\parbox{1\textwidth}{#1}} +% V1.8 compsoc is partial width +\ifCLASSOPTIONcompsoc +% comparison with proofs suggests it's in the range of 92.1-92.3% +\long\def\@IEEEtitleabstractindextextbox#1{\parbox{0.922\textwidth}{\@IEEEcompsocnotconfonly{\rightskip\@flushglue\leftskip\z@skip}#1}} +\fi + +% formats the Title, authors names, affiliations and special paper notice +% THIS IS A CONTROLLED SPACING COMMAND! Do not allow blank lines or unintentional +% spaces to enter the definition - use % at the end of each line +\def\@maketitle{\newpage +\bgroup\par\vskip\IEEEtitletopspace\vskip\IEEEtitletopspaceextra\centering% +\ifCLASSOPTIONtechnote% technotes, V1.8a abstract and index terms are not treated differently for compsoc technotes + {\bfseries\large\@IEEEcompsoconly{\Large\sffamily}\@title\par}\vskip 1.3em{\lineskip .5em\@IEEEcompsoconly{\large\sffamily}\@author + \@IEEEspecialpapernotice\par}\relax +\else% not a technote + \vskip0.2em{\Huge\ifCLASSOPTIONtransmag\bfseries\LARGE\fi\@IEEEcompsoconly{\sffamily}\@IEEEcompsocconfonly{\normalfont\normalsize\vskip 2\@IEEEnormalsizeunitybaselineskip + \bfseries\Large}\@IEEEcompsocnotconfonly{\vskip 0.75\@IEEEnormalsizeunitybaselineskip}\@title\par}\relax + \@IEEEcompsocnotconfonly{\vskip 0.5\@IEEEnormalsizeunitybaselineskip}\vskip1.0em\par% + % V1.6 handle \author differently if in conference mode + \ifCLASSOPTIONconference% + {\@IEEEspecialpapernotice\mbox{}\vskip\@IEEEauthorblockconfadjspace% + \mbox{}\hfill\begin{@IEEEauthorhalign}\@author\end{@IEEEauthorhalign}\hfill\mbox{}\par}\relax + \else% peerreviewca, peerreview or journal + \ifCLASSOPTIONpeerreviewca + % peerreviewca handles author names just like conference mode + {\@IEEEcompsoconly{\sffamily}\@IEEEspecialpapernotice\mbox{}\vskip\@IEEEauthorblockconfadjspace% + \mbox{}\hfill\begin{@IEEEauthorhalign}\@author\end{@IEEEauthorhalign}\hfill\mbox{}\par + {\@IEEEcompsoconly{\vskip 1.5em\relax + \@IEEEtitleabstractindextextbox{\@IEEEtitleabstractindextext}\par\noindent\hfill + \IEEEcompsocdiamondline\hfill\hbox{}\par}}}\relax + \else% journal, peerreview or transmag + \ifCLASSOPTIONtransmag + % transmag also handles author names just like conference mode + % it also uses \@IEEEtitleabstractindextex, but with one line less + % space above, and one more below + {\@IEEEspecialpapernotice\mbox{}\vskip\@IEEEauthorblockconfadjspace% + \mbox{}\hfill\begin{@IEEEauthorhalign}\@author\end{@IEEEauthorhalign}\hfill\mbox{}\par + {\vspace{0.5\baselineskip}\relax\@IEEEtitleabstractindextextbox{\@IEEEtitleabstractindextext}\vspace{-1\baselineskip}\par}}\relax + \else% journal or peerreview + {\lineskip.5em\@IEEEcompsoconly{\sffamily}\sublargesize\@author\@IEEEspecialpapernotice\par + {\@IEEEcompsoconly{\vskip 1.5em\relax + \@IEEEtitleabstractindextextbox{\@IEEEtitleabstractindextext}\par\noindent\hfill + \IEEEcompsocdiamondline\hfill\hbox{}\par}}}\relax + \fi + \fi + \fi +\fi\par\addvspace{0.5\baselineskip}\egroup} + + +% V1.7 Computer Society "diamond line" which follows index terms for nonconference papers +% V1.8a full width diamond line for single column use +\def\@IEEEcompsocdiamondlinei{\vrule depth 0pt height 0.5pt width 4cm\nobreak\hspace{7.5pt}\nobreak +\raisebox{-3.5pt}{\fontfamily{pzd}\fontencoding{U}\fontseries{m}\fontshape{n}\fontsize{11}{12}\selectfont\char70}\nobreak +\hspace{7.5pt}\nobreak\vrule depth 0pt height 0.5pt width 4cm\relax} +% V1.8a narrower width diamond line for double column use +\def\@IEEEcompsocdiamondlineii{\vrule depth 0pt height 0.5pt width 2.5cm\nobreak\hspace{7.5pt}\nobreak +\raisebox{-3.5pt}{\fontfamily{pzd}\fontencoding{U}\fontseries{m}\fontshape{n}\fontsize{11}{12}\selectfont\char70}\nobreak +\hspace{7.5pt}\nobreak\vrule depth 0pt height 0.5pt width 2.5cm\relax} +% V1.8a bare core without rules to base a last resort on for very narrow linewidths +\def\@IEEEcompsocdiamondlineiii{\mbox{}\nobreak\hspace{7.5pt}\nobreak +\raisebox{-3.5pt}{\fontfamily{pzd}\fontencoding{U}\fontseries{m}\fontshape{n}\fontsize{11}{12}\selectfont\char70}\nobreak +\hspace{7.5pt}\nobreak\mbox{}\relax} + +% V1.8a allow \IEEEcompsocdiamondline to adjust for different linewidths. +% Use \@IEEEcompsocdiamondlinei if its width is less than 0.66\linewidth (0.487 nominal for single column) +% if not, fall back to \@IEEEcompsocdiamondlineii if its width is less than 0.75\linewidth (0.659 nominal for double column) +% if all else fails, try to make a custom diamondline based on the abnormally narrow linewidth +\def\IEEEcompsocdiamondline{\settowidth{\@IEEEtrantmpdimenA}{\@IEEEcompsocdiamondlinei}\relax +\ifdim\@IEEEtrantmpdimenA<0.66\linewidth\relax\@IEEEcompsocdiamondlinei\relax +\else +\settowidth{\@IEEEtrantmpdimenA}{\@IEEEcompsocdiamondlineii}\relax +\ifdim\@IEEEtrantmpdimenA<0.75\linewidth\relax\@IEEEcompsocdiamondlineii\relax +\else +\settowidth{\@IEEEtrantmpdimenA}{\@IEEEcompsocdiamondlineiii}\relax +\@IEEEtrantmpdimenB=\linewidth\relax +\addtolength{\@IEEEtrantmpdimenB}{-1\@IEEEtrantmpdimenA}\relax +\vrule depth 0pt height 0.5pt width 0.33\@IEEEtrantmpdimenB\@IEEEcompsocdiamondlineiii\vrule depth 0pt height 0.5pt width 0.33\@IEEEtrantmpdimenB\relax +\fi\fi} + + +% V1.7 standard LateX2e \thanks, but with \itshape under compsoc. Also make it a \long\def +% We also need to trigger the one-shot footnote rule +\def\@IEEEtriggeroneshotfootnoterule{\global\@IEEEenableoneshotfootnoteruletrue} + + +\long\def\thanks#1{\footnotemark + \protected@xdef\@thanks{\@thanks + \protect\footnotetext[\the\c@footnote]{\@IEEEcompsoconly{\itshape + \protect\@IEEEtriggeroneshotfootnoterule\relax}\ignorespaces#1}}} +\let\@thanks\@empty + + +% V1.7 allow \author to contain \par's. This is needed to allow \thanks to contain \par. +\long\def\author#1{\gdef\@author{#1}} + + +% in addition to setting up IEEEitemize, we need to remove a baselineskip space above and +% below it because \list's \pars introduce blank lines because of the footnote struts. +\def\@IEEEsetupcompsocitemizelist{\def\labelitemi{$\bullet$}% +\setlength{\IEEElabelindent}{0pt}\setlength{\labelsep}{1.2em}\setlength{\parskip}{0pt}% +\setlength{\partopsep}{0pt}\setlength{\topsep}{0.5\baselineskip}\vspace{-1\baselineskip}\relax} + + +% flag for fake non-compsoc \IEEEcompsocthanksitem - prevents line break on very first item +\newif\if@IEEEbreakcompsocthanksitem \@IEEEbreakcompsocthanksitemfalse + +\ifCLASSOPTIONcompsoc +% V1.7 compsoc bullet item \thanks +% also, we need to redefine this to destroy the argument in \IEEEquantizevspace +\long\def\IEEEcompsocitemizethanks#1{\relax\@IEEEbreakcompsocthanksitemfalse\footnotemark + \protected@xdef\@thanks{\@thanks + \protect\footnotetext[\the\c@footnote]{\itshape\protect\@IEEEtriggeroneshotfootnoterule + {\let\IEEEiedlistdecl\relax\protect\begin{IEEEitemize}[\protect\@IEEEsetupcompsocitemizelist]\ignorespaces#1\relax + \protect\end{IEEEitemize}}\protect\vspace{-1\baselineskip}}}} +\DeclareRobustCommand*{\IEEEcompsocthanksitem}{\item} +\else +% non-compsoc, allow for dual compilation via rerouting to normal \thanks +\long\def\IEEEcompsocitemizethanks#1{\thanks{#1}} +% redirect to "pseudo-par" \hfil\break\indent after swallowing [] from \IEEEcompsocthanksitem[] +\DeclareRobustCommand{\IEEEcompsocthanksitem}{\@ifnextchar [{\@IEEEthanksswallowoptionalarg}% +{\@IEEEthanksswallowoptionalarg[\relax]}} +% be sure and break only after first item, be sure and ignore spaces after optional argument +\def\@IEEEthanksswallowoptionalarg[#1]{\relax\if@IEEEbreakcompsocthanksitem\hfil\break +\indent\fi\@IEEEbreakcompsocthanksitemtrue\ignorespaces} +\fi + + +% V1.6b define the \IEEEpeerreviewmaketitle as needed +\ifCLASSOPTIONpeerreview +\def\IEEEpeerreviewmaketitle{\@IEEEcleardoublepage{empty}% +\ifCLASSOPTIONtwocolumn +\twocolumn[{\IEEEquantizevspace{\@IEEEpeerreviewmaketitle}[\IEEEquantizedisabletitlecmds]{0pt}[-\topskip]{\baselineskip}{\@IEEENORMtitlevspace}{\@IEEEMINtitlevspace}}] +\else +\newpage\@IEEEpeerreviewmaketitle\@IEEEstatictitlevskip +\fi +\thispagestyle{IEEEtitlepagestyle}} +\else +% \IEEEpeerreviewmaketitle does nothing if peer review option has not been selected +\def\IEEEpeerreviewmaketitle{\relax} +\fi + +% peerreview formats the repeated title like the title in journal papers. +\def\@IEEEpeerreviewmaketitle{\bgroup\par\addvspace{0.5\baselineskip}\centering\@IEEEcompsoconly{\sffamily}% +\normalfont\normalsize\vskip0.2em{\Huge\@title\par}\vskip1.0em\par +\par\addvspace{0.5\baselineskip}\egroup} + + + +% V1.6 +% this is a static rubber spacer between the title/authors and the main text +% used for single column text, or when the title appears in the first column +% of two column text (technotes). +\def\@IEEEstatictitlevskip{{\normalfont\normalsize +% adjust spacing to next text +% v1.6b handle peer review papers +\ifCLASSOPTIONpeerreview +% for peer review papers, the same value is used for both title pages +% regardless of the other paper modes + \vskip 1\baselineskip plus 0.375\baselineskip minus 0.1875\baselineskip +\else + \ifCLASSOPTIONconference% conference + \vskip 1\baselineskip plus 0.375\baselineskip minus 0.1875\baselineskip% + \else% + \ifCLASSOPTIONtechnote% technote + \vskip 1\baselineskip plus 0.375\baselineskip minus 0.1875\baselineskip% + \else% journal uses more space + \vskip 2.5\baselineskip plus 0.75\baselineskip minus 0.375\baselineskip% + \fi + \fi +\fi}} + + +% set the nominal and minimum values for the quantized title spacer +% the quantization algorithm will not allow the spacer size to +% become less than \@IEEEMINtitlevspace - instead it will be lengthened +% default to journal values +\def\@IEEENORMtitlevspace{2.5\baselineskip} +\def\@IEEEMINtitlevspace{2\baselineskip} +% conferences and technotes need tighter spacing +\ifCLASSOPTIONconference% conference + \def\@IEEENORMtitlevspace{1\baselineskip} + \def\@IEEEMINtitlevspace{0.75\baselineskip} +\fi +\ifCLASSOPTIONtechnote% technote + \def\@IEEENORMtitlevspace{1\baselineskip} + \def\@IEEEMINtitlevspace{0.75\baselineskip} +\fi + + +% V1.8a +\def\IEEEquantizevspace{\begingroup\@ifstar{\@IEEEquantizevspacestarformtrue\@IEEEquantizevspace}{\@IEEEquantizevspacestarformfalse\@IEEEquantizevspace}} +% \IEEEquantizevspace[output dimen register]{object}[object decl] +% {top baselineskip} +% [offset][prevdepth][lineskip limit][lineskip] +% {unit height}{nominal vspace}{minimum vspace} +% +% Calculates and creates the vspace needed to make the combined height with +% the given object an integer multiple of the given unit height. This command +% is more general than the older \@IEEEdynamictitlevspace it replaces. +% +% The star form has no effect at present, but is reserved for future use. +% +% If the optional argument [output dimen register] is given, the calculated +% vspace height is stored in the given output dimen (or skip) register +% and no other action is taken, otherwise the object followed by a vspace* +% of the appropriate height is evaluated/output. +% +% The optional object decl (declarations) is code that is evaluated just +% before the object's height is evaluated. Its intented purpose is to allow +% for the alteration or disabling of code within the object during internal +% height evaluation (e.g., \long\def\thanks#1{\relax} ). +% This special code is not invoked if/when the object is rendered at the end. +% +% The nominal vspace is the target value of the added vspace and the minimum +% vspace is the lower allowed limit. The vspacer will be the value that achieves +% integral overall height, in terms of the given unit height, that is closest +% to the nominal vspace and that is not less than the specified minimum vspace. +% +% The line spacing algorithm of TeX is somewhat involved and requires special +% care with regard to the first line of a vertical list (which is indicated +% when \prevdepth is -1000pt or less). top baselineskip specifies the +% baselineskip or topskip used prior to the object. If the height of the +% first line of the object is greater than the given top baselineskip, then +% the top baselineskip is subtracted from the height of the first line and +% that difference is considered along with the rest of the object height +% (because the object will be shifted down by an amount = +% top line height - top baselineskip). Otherwise, the height of the first line +% of the object is ignored as far as the calculations are concerned. +% This algorithm is adequate for objects that appear at the top of a page +% (e.g., titles) where \topskip spacing is used. +% +% However, as explained on page 78 of the TeXbook, interline spacing is more +% complex when \baselineskip is being used (indicated by \prevdepth > +% -1000pt). The four optional parameters offset, prevdepth, lineskip limit and +% lineskip are assumed to be equal to be 0pt, \prevdepth, \lineskiplimit and +% \lineskip, respectively, if they are omitted. +% +% The prevdepth is the depth of the line before the object, the lineskip limit +% specifies how close the top of the object can come to the bottom of the +% previous line before \baselineskip is ignored and \lineskip is inserted +% between the object and the line above it. Lineskip does not come into +% play unless the first line of the object is high enough to "get too close" +% (as specified by lineskiplimit) to the line before it. The the prevdepth, +% lineskip limit, and lineskip optional parameters are not needed for the +% first object/line on a page (i.e., prevdepth <= -1000pt) where the simplier +% \topskip spacing rules are in effect. +% +% Offset is a manual adjustment that is added to the height calculations of +% object irrespective of the value of \prevdepth. It is useful when the top +% baselineskip will result in a noninteger unit height object placement even +% if the object itself has integral height. e.g., a footnotesize baselineskip +% is used before the object, thus an offset of, say -3pt, can be given as a +% correction. + +% Common combinations of these parameters include: +% +% top baselineskip: (and default values for offset, prevdepth, etc.) +% \topskip % for objects that appear at the top of a page +% \maxdimen % always ignore the height of the top line +% 0pt % always consider any positive height of the top line +% +% for objects to appear inline in normal text: +% top baselineskip = \baselineskip +% +% set prevdepth = -1000pt and top baselineskip = 0pt to consider the +% overall height of the object without any other external skip +% consideration + +\newif\if@IEEEquantizevspacestarform % flag to indicate star form +\newif\if@IEEEquantizevspaceuseoutdimenreg % flag to indicate output dimen register is to be used +% Use our own private registers because the object could contain a +% structure that uses the existing tmp scratch pad registers +\newdimen\@IEEEquantizeheightA +\newdimen\@IEEEquantizeheightB +\newdimen\@IEEEquantizeheightC +\newdimen\@IEEEquantizeprevdepth % need to save this early as can change +\newcount\@IEEEquantizemultiple +\newbox\@IEEEquantizeboxA + + +\def\@IEEEquantizevspace{\@ifnextchar [{\@IEEEquantizevspaceuseoutdimenregtrue\@@IEEEquantizevspace}{\@IEEEquantizevspaceuseoutdimenregfalse\@@IEEEquantizevspace[]}} + + +\long\def\@@IEEEquantizevspace[#1]#2{\relax +% acquire and store +% #1 optional output dimen register +% #2 object +\edef\@IEEEquantizeoutdimenreg{#1}\relax +% allow for object specifications that contain parameters +\@IEEEtrantmptoksA={#2}\relax +\long\edef\@IEEEquantizeobject{\the\@IEEEtrantmptoksA}\relax +\@ifnextchar [{\@@@IEEEquantizevspace}{\@@@IEEEquantizevspace[\relax]}} + +\long\def\@@@IEEEquantizevspace[#1]#2{\relax +% acquire and store +% [#1] optional object decl, is \relax if not given by user +% #2 top baselineskip +% allow for object decl specifications that have parameters +\@IEEEtrantmptoksA={#1}\relax +\long\edef\@IEEEquantizeobjectdecl{\the\@IEEEtrantmptoksA}\relax +\edef\@IEEEquantizetopbaselineskip{#2}\ivIEEEquantizevspace} + +% acquire optional argument set and store +% [offset][prevdepth][lineskip limit][lineskip] +\def\ivIEEEquantizevspace{\@ifnextchar [{\@vIEEEquantizevspace}{\@vIEEEquantizevspace[0pt]}} +\def\@vIEEEquantizevspace[#1]{\edef\@IEEEquantizeoffset{#1}\@ifnextchar [{\@viIEEEquantizevspace}{\@viIEEEquantizevspace[\prevdepth]}} +\def\@viIEEEquantizevspace[#1]{\@IEEEquantizeprevdepth=#1\relax\@ifnextchar [{\@viiIEEEquantizevspace}{\@viiIEEEquantizevspace[\lineskiplimit]}} +\def\@viiIEEEquantizevspace[#1]{\edef\@IEEEquantizelineskiplimit{#1}\@ifnextchar [{\@viiiIEEEquantizevspace}{\@viiiIEEEquantizevspace[\lineskip]}} +\def\@viiiIEEEquantizevspace[#1]{\edef\@IEEEquantizelineskip{#1}\@ixIEEEquantizevspace} + +% main routine +\def\@ixIEEEquantizevspace#1#2#3{\relax +\edef\@IEEEquantizeunitheight{#1}\relax +\edef\@IEEEquantizenomvspace{#2}\relax +\edef\@IEEEquantizeminvspace{#3}\relax +% \@IEEEquantizeoutdimenreg +% \@IEEEquantizeobject +% \@IEEEquantizeobjectdecl +% \@IEEEquantizetopbaselineskip +% \@IEEEquantizeoffset +% \@IEEEquantizeprevdepth +% \@IEEEquantizelineskiplimit +% \@IEEEquantizelineskip +% \@IEEEquantizeunitheight +% \@IEEEquantizenomvspace +% \@IEEEquantizeminvspace +% get overall height of object +\setbox\@IEEEquantizeboxA\vbox{\begingroup\@IEEEquantizeobjectdecl\@IEEEquantizeobject\relax\endgroup}\relax +\@IEEEquantizeheightA\ht\@IEEEquantizeboxA\relax +% get height of first line of object +\setbox\@IEEEquantizeboxA\vtop{\begingroup\@IEEEquantizeobjectdecl\@IEEEquantizeobject\relax\endgroup}\relax +\@IEEEquantizeheightB\ht\@IEEEquantizeboxA\relax +\ifdim\@IEEEquantizeprevdepth>-1000pt\relax % prevdepth > -1000pf means full baselineskip\lineskip rules in effect +% lineskip spacing rule takes effect if height of top line > baselineskip - prevdepth - lineskiplimit, +% otherwise the baselineskip rule is in effect and the height of the first line does not matter at all. +\@IEEEquantizeheightC=\@IEEEquantizetopbaselineskip\relax +\advance\@IEEEquantizeheightC-\@IEEEquantizeprevdepth\relax +\advance\@IEEEquantizeheightC-\@IEEEquantizelineskiplimit\relax % this works even though \@IEEEquantizelineskiplimit is a macro because TeX allows --10pt notation +\ifdim\@IEEEquantizeheightB>\@IEEEquantizeheightC\relax +% lineskip spacing rule is in effect i.e., the object is going to be shifted down relative to the +% baselineskip set position by its top line height (already a part of the total height) + prevdepth + lineskip - baselineskip +\advance\@IEEEquantizeheightA\@IEEEquantizeprevdepth\relax +\advance\@IEEEquantizeheightA\@IEEEquantizelineskip\relax +\advance\@IEEEquantizeheightA-\@IEEEquantizetopbaselineskip\relax +\else +% height of first line <= \@IEEEquantizetopbaselineskip - \@IEEEquantizeprevdepth - \@IEEEquantizelineskiplimit +% standard baselineskip rules are in effect, so don't consider height of first line +\advance\@IEEEquantizeheightA-\@IEEEquantizeheightB\relax +\fi +% +\else % prevdepth <= -1000pt, simplier \topskip type rules in effect +\ifdim\@IEEEquantizeheightB>\@IEEEquantizetopbaselineskip +% height of top line (already included in the total height) in excess of +% baselineskip is the amount it will be downshifted +\advance\@IEEEquantizeheightA-\@IEEEquantizetopbaselineskip\relax +\else +% height of first line is irrelevant, remove it +\advance\@IEEEquantizeheightA-\@IEEEquantizeheightB\relax +\fi +\fi % prevdepth <= -1000pt +% +% adjust height for any manual offset +\advance\@IEEEquantizeheightA\@IEEEquantizeoffset\relax +% add in nominal spacer +\advance\@IEEEquantizeheightA\@IEEEquantizenomvspace\relax +% check for nonzero unitheight +\@IEEEquantizeheightB=\@IEEEquantizeunitheight\relax +\ifnum\@IEEEquantizeheightB=0\relax +\@IEEEclspkgerror{IEEEquantizevspace unit height cannot be zero. Assuming 10pt.}% +{Division by zero is not allowed.} +\@IEEEquantizeheightB=10pt\relax +\fi +% get integer number of lines +\@IEEEquantizemultiple=\@IEEEquantizeheightA\relax +\divide\@IEEEquantizemultiple\@IEEEquantizeheightB\relax +% set A to contain the excess height over the \@IEEEquantizemultiple of lines +% A = height - multiple*unitheight +\@IEEEquantizeheightC\@IEEEquantizeheightB\relax +\multiply\@IEEEquantizeheightC\@IEEEquantizemultiple\relax +\advance\@IEEEquantizeheightA-\@IEEEquantizeheightC\relax +% set B to contain the height short of \@IEEEquantizemultiple+1 of lines +% B = unitheight - A +\advance\@IEEEquantizeheightB-\@IEEEquantizeheightA\relax +% choose A or B based on which is closer +\@IEEEquantizeheightC\@IEEEquantizenomvspace\relax +\ifdim\@IEEEquantizeheightA<\@IEEEquantizeheightB\relax +% C = nomvspace - A, go with lower +\advance\@IEEEquantizeheightC-\@IEEEquantizeheightA\relax +\else +% C = nomvspace + B, go with upper +\advance\@IEEEquantizeheightC\@IEEEquantizeheightB\relax +\fi +% if violate lower bound, use next integer bound +\ifdim\@IEEEquantizeheightC<\@IEEEquantizeminvspace\relax +% A + B = unitheight +\advance\@IEEEquantizeheightC\@IEEEquantizeheightA\relax +\advance\@IEEEquantizeheightC\@IEEEquantizeheightB\relax +\fi +% export object and spacer outside of group +\global\let\@IEEEquantizeobjectout\@IEEEquantizeobject\relax +\global\@IEEEquantizeheightC\@IEEEquantizeheightC\relax +\endgroup +\if@IEEEquantizevspaceuseoutdimenreg +\@IEEEquantizeoutdimenreg=\@IEEEquantizeheightC\relax +\else +\@IEEEquantizeobjectout\relax +\vskip\@IEEEquantizeheightC\relax +\fi} + + +% user command to disable all global assignments, possible use within object decl +\def\IEEEquantizedisableglobal{\let\global\relax +\let\gdef\def +\let\xdef\edef} +% user command to allow for the disabling of \thanks and other commands, possible use within object decl +\def\IEEEquantizedisabletitlecmds{\long\def\thanks##1{\relax}\relax +\long\def\IEEEcompsocitemizethanks##1{\relax}\def\newpage{\relax}} + + + + + +% V1.6 +% we allow the user access to the last part of the title area +% useful in emergencies such as when a different spacing is needed +% This text is NOT compensated for in the dynamic sizer. +\let\@IEEEaftertitletext=\relax +\long\def\IEEEaftertitletext#1{\def\@IEEEaftertitletext{#1}} + + +% V1.7 provide a way for users to enter abstract and keywords +% into the onecolumn title are. This text is compensated for +% in the dynamic sizer. +\let\@IEEEtitleabstractindextext=\relax +\long\def\IEEEtitleabstractindextext#1{\def\@IEEEtitleabstractindextext{#1}} + +% V1.7 provide a way for users to get the \@IEEEtitleabstractindextext if +% not in compsoc or transmag journal mode - this way abstract and keywords +% can still be placed in their conventional position if not in those modes. +\def\IEEEdisplaynontitleabstractindextext{% +% display for all conference formats +\ifCLASSOPTIONconference\@IEEEtitleabstractindextext\relax +\else% non-conferences + % V1.8a display for all technotes + \ifCLASSOPTIONtechnote\@IEEEtitleabstractindextext\relax + % V1.8a add diamond line after abstract and index terms for compsoc technotes + \@IEEEcompsoconly{\noindent\hfill\IEEEcompsocdiamondline\hfill\hbox{}\par}\relax + \else % non-conferences and non-technotes + \ifCLASSOPTIONcompsoc% display if not compsoc and not transmag + \else + \ifCLASSOPTIONtransmag + \else% not compsoc journal nor transmag journal + \@IEEEtitleabstractindextext\relax + \fi + \fi + \fi +\fi} + + +% command to allow alteration of baselinestretch, but only if the current +% baselineskip is unity. Used to tweak the compsoc abstract and keywords line spacing. +\def\@IEEEtweakunitybaselinestretch#1{{\def\baselinestretch{1}\selectfont +\global\@tempskipa\baselineskip}\ifnum\@tempskipa=\baselineskip% +\def\baselinestretch{#1}\selectfont\fi\relax} + + +% abstract and keywords are in \small, except +% for 9pt docs in which they are in \footnotesize +% Because 9pt docs use an 8pt footnotesize, \small +% becomes a rather awkward 8.5pt +\def\@IEEEabskeysecsize{\small} +\ifx\CLASSOPTIONpt\@IEEEptsizenine + \def\@IEEEabskeysecsize{\footnotesize} +\fi + +% compsoc journals use \footnotesize, compsoc conferences use normalsize +\@IEEEcompsoconly{\def\@IEEEabskeysecsize{\footnotesize}} +\@IEEEcompsocconfonly{\def\@IEEEabskeysecsize{\small}} + + +% V1.6 have abstract and keywords strip leading spaces, pars and newlines +% so that spacing is more tightly controlled. +\def\abstract{\normalfont + \if@twocolumn + \@IEEEabskeysecsize\bfseries\textit{\abstractname}---\relax + \else + \bgroup\par\addvspace{0.5\baselineskip}\centering\vspace{-1.78ex}\@IEEEabskeysecsize\textbf{\abstractname}\par\addvspace{0.5\baselineskip}\egroup\quotation\@IEEEabskeysecsize + \fi\@IEEEgobbleleadPARNLSP} +% V1.6 The IEEE wants only 1 pica from end of abstract to introduction heading when in +% conference mode (the heading already has this much above it) +\def\endabstract{\relax\ifCLASSOPTIONconference\vspace{0ex}\else\vspace{1.34ex}\fi\par\if@twocolumn\else\endquotation\fi + \normalfont\normalsize} + +\def\IEEEkeywords{\normalfont + \if@twocolumn + \@IEEEabskeysecsize\bfseries\textit{\IEEEkeywordsname}---\relax + \else + \bgroup\par\addvspace{0.5\baselineskip}\centering\@IEEEabskeysecsize\textbf{\IEEEkeywordsname}\par\addvspace{0.5\baselineskip}\egroup\quotation\@IEEEabskeysecsize + \fi\@IEEEgobbleleadPARNLSP} +\def\endIEEEkeywords{\relax\ifCLASSOPTIONtechnote\vspace{1.34ex}\else\vspace{0.67ex}\fi + \par\if@twocolumn\else\endquotation\fi% + \normalfont\normalsize} + +% V1.7 compsoc keywords index terms +\ifCLASSOPTIONcompsoc + \ifCLASSOPTIONconference% compsoc conference +\def\abstract{\normalfont\@IEEEtweakunitybaselinestretch{1.15}\bfseries + \if@twocolumn + \@IEEEabskeysecsize\noindent\textit{\abstractname}---\relax + \else + \bgroup\par\addvspace{0.5\baselineskip}\centering\vspace{-1.78ex}\@IEEEabskeysecsize\textbf{\abstractname}\par\addvspace{0.5\baselineskip}\egroup\quotation\@IEEEabskeysecsize% + \fi\@IEEEgobbleleadPARNLSP} +\def\IEEEkeywords{\normalfont\@IEEEtweakunitybaselinestretch{1.15}\bfseries + \if@twocolumn + \@IEEEabskeysecsize\vskip 0.5\baselineskip plus 0.25\baselineskip minus 0.25\baselineskip\noindent + \textit{\IEEEkeywordsname}---\relax + \else + \bgroup\par\addvspace{0.5\baselineskip}\centering\@IEEEabskeysecsize\textbf{\IEEEkeywordsname}\par\addvspace{0.5\baselineskip}\egroup\quotation\@IEEEabskeysecsize% + \fi\@IEEEgobbleleadPARNLSP} + \else% compsoc not conference +\def\abstract{\normalfont\@IEEEtweakunitybaselinestretch{1.15}\sffamily + \if@twocolumn + \@IEEEabskeysecsize\noindent\textbf{\abstractname}---\relax + \else + \bgroup\par\addvspace{0.5\baselineskip}\centering\vspace{-1.78ex}\@IEEEabskeysecsize\textbf{\abstractname}\par\addvspace{0.5\baselineskip}\egroup\quotation\@IEEEabskeysecsize% + \fi\@IEEEgobbleleadPARNLSP} +\def\IEEEkeywords{\normalfont\@IEEEtweakunitybaselinestretch{1.15}\sffamily + \if@twocolumn + \@IEEEabskeysecsize\vskip 0.5\baselineskip plus 0.25\baselineskip minus 0.25\baselineskip\noindent + \textbf{\IEEEkeywordsname}---\relax + \else + \bgroup\par\addvspace{0.5\baselineskip}\centering\@IEEEabskeysecsize\textbf{\IEEEkeywordsname}\par\addvspace{0.5\baselineskip}\egroup\quotation\@IEEEabskeysecsize% + \fi\@IEEEgobbleleadPARNLSP} + \fi +\fi + +% V1.8 transmag keywords index terms +% no abstract name, use indentation +\ifCLASSOPTIONtransmag +\def\abstract{\normalfont\parindent 1em\relax + \if@twocolumn + \@IEEEabskeysecsize\bfseries\indent + \else + \bgroup\par\addvspace{0.5\baselineskip}\centering\vspace{-1.78ex}\@IEEEabskeysecsize + \textbf{\abstractname}\par\addvspace{0.5\baselineskip}\egroup\quotation\@IEEEabskeysecsize + \fi\@IEEEgobbleleadPARNLSP} + +\def\IEEEkeywords{\normalfont\parindent 1em\relax + \if@twocolumn + \@IEEEabskeysecsize\vspace{1\baselineskip}\bfseries\indent\textit{\IEEEkeywordsname}---\relax + \else + \bgroup\par\vspace{1\baselineskip}\centering\@IEEEabskeysecsize + \textbf{\IEEEkeywordsname}\par\addvspace{0.5\baselineskip}\egroup\quotation\@IEEEabskeysecsize + \fi\@IEEEgobbleleadPARNLSP} +\fi + + + +% gobbles all leading \, \\ and \par, upon finding first token that +% is not a \ , \\ or a \par, it ceases and returns that token +% +% used to strip leading \, \\ and \par from the input +% so that such things in the beginning of an environment will not +% affect the formatting of the text +\long\def\@IEEEgobbleleadPARNLSP#1{\let\@IEEEswallowthistoken=0% +\let\@IEEEgobbleleadPARNLSPtoken#1% +\let\@IEEEgobbleleadPARtoken=\par% +\let\@IEEEgobbleleadNLtoken=\\% +\let\@IEEEgobbleleadSPtoken=\ % +\def\@IEEEgobbleleadSPMACRO{\ }% +\ifx\@IEEEgobbleleadPARNLSPtoken\@IEEEgobbleleadPARtoken% +\let\@IEEEswallowthistoken=1% +\fi% +\ifx\@IEEEgobbleleadPARNLSPtoken\@IEEEgobbleleadNLtoken% +\let\@IEEEswallowthistoken=1% +\fi% +\ifx\@IEEEgobbleleadPARNLSPtoken\@IEEEgobbleleadSPtoken% +\let\@IEEEswallowthistoken=1% +\fi% +% a control space will come in as a macro +% when it is the last one on a line +\ifx\@IEEEgobbleleadPARNLSPtoken\@IEEEgobbleleadSPMACRO% +\let\@IEEEswallowthistoken=1% +\fi% +% if we have to swallow this token, do so and taste the next one +% else spit it out and stop gobbling +\ifx\@IEEEswallowthistoken 1\let\@IEEEnextgobbleleadPARNLSP=\@IEEEgobbleleadPARNLSP\else% +\let\@IEEEnextgobbleleadPARNLSP=#1\fi% +\@IEEEnextgobbleleadPARNLSP}% + + + + +% TITLING OF SECTIONS +\def\@IEEEsectpunct{:\ \,} % Punctuation after run-in section heading (headings which are + % part of the paragraphs), need little bit more than a single space + % spacing from section number to title +% compsoc conferences use regular period/space punctuation +\ifCLASSOPTIONcompsoc +\ifCLASSOPTIONconference +\def\@IEEEsectpunct{.\ } +\fi\fi + + +\def\@seccntformat#1{\csname the#1dis\endcsname\hskip 0.5em\relax} + +\ifCLASSOPTIONcompsoc +% compsoc journals need extra spacing +\ifCLASSOPTIONconference\else +\def\@seccntformat#1{\csname the#1dis\endcsname\hskip 1em\relax} +\fi\fi + +%v1.7 put {} after #6 to allow for some types of user font control +%and use \@@par rather than \par +\def\@sect#1#2#3#4#5#6[#7]#8{% + \ifnum #2>\c@secnumdepth + \let\@svsec\@empty + \else + \refstepcounter{#1}% + % load section label and spacer into \@svsec + \protected@edef\@svsec{\@seccntformat{#1}\relax}% + \fi% + \@tempskipa #5\relax + \ifdim \@tempskipa>\z@% tempskipa determines whether is treated as a high + \begingroup #6{\relax% or low level heading + \noindent % subsections are NOT indented + % print top level headings. \@svsec is label, #8 is heading title + % The IEEE does not block indent the section title text, it flows like normal + {\hskip #3\relax\@svsec}{\interlinepenalty \@M #8\@@par}}% + \endgroup + \addcontentsline{toc}{#1}{\ifnum #2>\c@secnumdepth\relax\else + \protect\numberline{\csname the#1\endcsname}\fi#7}% + \else % printout low level headings + % svsechd seems to swallow the trailing space, protect it with \mbox{} + % got rid of sectionmark stuff + \def\@svsechd{#6{\hskip #3\relax\@svsec #8\@IEEEsectpunct\mbox{}}% + \addcontentsline{toc}{#1}{\ifnum #2>\c@secnumdepth\relax\else + \protect\numberline{\csname the#1\endcsname}\fi#7}}% + \fi%skip down + \@xsect{#5}} + + +% section* handler +%v1.7 put {} after #4 to allow for some types of user font control +%and use \@@par rather than \par +\def\@ssect#1#2#3#4#5{\@tempskipa #3\relax + \ifdim \@tempskipa>\z@ + %\begingroup #4\@hangfrom{\hskip #1}{\interlinepenalty \@M #5\par}\endgroup + % The IEEE does not block indent the section title text, it flows like normal + \begingroup \noindent #4{\relax{\hskip #1}{\interlinepenalty \@M #5\@@par}}\endgroup + % svsechd swallows the trailing space, protect it with \mbox{} + \else \def\@svsechd{#4{\hskip #1\relax #5\@IEEEsectpunct\mbox{}}}\fi + \@xsect{#3}} + + +%% SECTION heading spacing and font +%% +% arguments are: #1 - sectiontype name +% (for \@sect) #2 - section level +% #3 - section heading indent +% #4 - top separation (absolute value used, neg indicates not to indent main text) +% If negative, make stretch parts negative too! +% #5 - (absolute value used) positive: bottom separation after heading, +% negative: amount to indent main text after heading +% Both #4 and #5 negative means to indent main text and use negative top separation +% #6 - font control +% You've got to have \normalfont\normalsize in the font specs below to prevent +% trouble when you do something like: +% \section{Note}{\ttfamily TT-TEXT} is known to ... +% The IEEE sometimes REALLY stretches the area before a section +% heading by up to about 0.5in. However, it may not be a good +% idea to let LaTeX have quite this much rubber. +\ifCLASSOPTIONconference% +% The IEEE wants section heading spacing to decrease for conference mode +\def\section{\@startsection{section}{1}{\z@}{1.5ex plus 1.5ex minus 0.5ex}% +{0.7ex plus 1ex minus 0ex}{\normalfont\normalsize\centering\scshape}}% +\def\subsection{\@startsection{subsection}{2}{\z@}{1.5ex plus 1.5ex minus 0.5ex}% +{0.7ex plus .5ex minus 0ex}{\normalfont\normalsize\itshape}}% +\else % for journals +\def\section{\@startsection{section}{1}{\z@}{3.0ex plus 1.5ex minus 1.5ex}% V1.6 3.0ex from 3.5ex +{0.7ex plus 1ex minus 0ex}{\normalfont\normalsize\centering\scshape}}% +\def\subsection{\@startsection{subsection}{2}{\z@}{3.5ex plus 1.5ex minus 1.5ex}% +{0.7ex plus .5ex minus 0ex}{\normalfont\normalsize\itshape}}% +\fi + +% for both journals and conferences +% decided to put in a little rubber above the section, might help somebody +\def\subsubsection{\@startsection{subsubsection}{3}{\parindent}{0ex plus 0.1ex minus 0.1ex}% +{0ex}{\normalfont\normalsize\itshape}}% +\def\paragraph{\@startsection{paragraph}{4}{2\parindent}{0ex plus 0.1ex minus 0.1ex}% +{0ex}{\normalfont\normalsize\itshape}}% + + +% compsoc +\ifCLASSOPTIONcompsoc +\ifCLASSOPTIONconference +% compsoc conference +\def\section{\@startsection{section}{1}{\z@}{1\baselineskip plus 0.25\baselineskip minus 0.25\baselineskip}% +{1\baselineskip plus 0.25\baselineskip minus 0.25\baselineskip}{\normalfont\large\bfseries}}% +\def\subsection{\@startsection{subsection}{2}{\z@}{1\baselineskip plus 0.25\baselineskip minus 0.25\baselineskip}% +{1\baselineskip plus 0.25\baselineskip minus 0.25\baselineskip}{\normalfont\sublargesize\bfseries}}% +\def\subsubsection{\@startsection{subsubsection}{3}{\z@}{1\baselineskip plus 0.25\baselineskip minus 0.25\baselineskip}% +{0ex}{\normalfont\normalsize\bfseries}}% +\def\paragraph{\@startsection{paragraph}{4}{2\parindent}{0ex plus 0.1ex minus 0.1ex}% +{0ex}{\normalfont\normalsize}}% +\else% compsoc journals +% use negative top separation as compsoc journals do not indent paragraphs after section titles +\def\section{\@startsection{section}{1}{\z@}{-3.5ex plus -2ex minus -1.5ex}% +{0.7ex plus 1ex minus 0ex}{\normalfont\sublargesize\sffamily\bfseries\scshape}}% +% Note that subsection and smaller may not be correct for the Computer Society, +% I have to look up an example. +\def\subsection{\@startsection{subsection}{2}{\z@}{-3.5ex plus -1.5ex minus -1.5ex}% +{0.7ex plus .5ex minus 0ex}{\normalfont\normalsize\sffamily\bfseries}}% +\def\subsubsection{\@startsection{subsubsection}{3}{\z@}{-2.5ex plus -1ex minus -1ex}% +{0.5ex plus 0.5ex minus 0ex}{\normalfont\normalsize\sffamily\itshape}}% +\def\paragraph{\@startsection{paragraph}{4}{2\parindent}{-0ex plus -0.1ex minus -0.1ex}% +{0ex}{\normalfont\normalsize}}% +\fi\fi + +% transmag +\ifCLASSOPTIONtransmag +\def\subsection{\@startsection{subsection}{2}{0.75\parindent}{3.5ex plus 1.5ex minus 1.5ex}% +{0.7ex plus .5ex minus 0ex}{\normalfont\normalsize\itshape}}% +\def\subsubsection{\@startsection{subsubsection}{3}{1.25\parindent}{0.1ex plus 0.1ex minus 0.1ex}% +{0.1ex}{\normalfont\normalsize\itshape}}% +\fi + + +% V1.8a provide for a raised line Introduction section for use with Computer +% Society papers. We have to remove any spacing glue after the section +% heading and then remove the blank line for the new paragraph after it. +% LaTeX's section handler alters \everypar and we need to propogate those +% changes outside of the \parbox lest there be spacing problems at the top +% of the next section. +\def\IEEEraisesectionheading#1{\noindent\raisebox{1.5\baselineskip}[0pt][0pt]{\parbox[b]{\columnwidth}{#1\unskip\global\everypar=\everypar}}\vspace{-1\baselineskip}\vspace{-\parskip}\par} + + + +%% ENVIRONMENTS +% "box" symbols at end of proofs +\def\IEEEQEDclosed{\mbox{\rule[0pt]{1.3ex}{1.3ex}}} % for a filled box +% V1.6 some journals use an open box instead that will just fit around a closed one +\def\IEEEQEDopen{{\setlength{\fboxsep}{0pt}\setlength{\fboxrule}{0.2pt}\fbox{\rule[0pt]{0pt}{1.3ex}\rule[0pt]{1.3ex}{0pt}}}} +\ifCLASSOPTIONcompsoc +\def\IEEEQED{\IEEEQEDopen} % default to open for compsoc +\else +\def\IEEEQED{\IEEEQEDclosed} % otherwise default to closed +\fi + +%V1.8 flag to indicate if QED symbol is to be shown +\newif\if@IEEEQEDshow \@IEEEQEDshowtrue +\def\IEEEproofindentspace{2\parindent}% V1.8 allow user to change indentation amount if desired +% v1.7 name change to avoid namespace collision with amsthm. Also add support +% for an optional argument. +\def\IEEEproof{\@ifnextchar[{\@IEEEproof}{\@IEEEproof[\IEEEproofname]}} +\def\@IEEEproof[#1]{\@IEEEQEDshowtrue\par\noindent\hspace{\IEEEproofindentspace}{\itshape #1: }} +\def\endIEEEproof{\if@IEEEQEDshow\hspace*{\fill}\nobreakspace\IEEEQED\fi\par} +% qedhere for equation environments, similar to AMS \qedhere +\def\IEEEQEDhereeqn{\global\@IEEEQEDshowfalse\eqno\let\eqno\relax\let\leqno\relax + \let\veqno\relax\hbox{\IEEEQED}} +% IEEE style qedhere for IEEEeqnarray and other environments +\def\IEEEQEDhere{\global\@IEEEQEDshowfalse\IEEEQED} +% command to disable QED at end of IEEEproof +\def\IEEEQEDoff{\global\@IEEEQEDshowfalse} + + +%\itemindent is set to \z@ by list, so define new temporary variable +\newdimen\@IEEEtmpitemindent + +\ifCLASSOPTIONcompsoc +% V1.8a compsoc uses bold theorem titles, a period instead of a colon, vertical spacing, and hanging indentation +% V1.8 allow long theorem names to break across lines. +% Thanks to Miquel Payaro for reporting this. +\def\@begintheorem#1#2{\@IEEEtmpitemindent\itemindent\relax + \topsep 0.2\@IEEEnormalsizeunitybaselineskip plus 0.26\@IEEEnormalsizeunitybaselineskip minus 0.05\@IEEEnormalsizeunitybaselineskip + \rmfamily\trivlist\hangindent\parindent% + \item[]\textit{\bfseries\noindent #1\ #2.} \itemindent\@IEEEtmpitemindent\relax} +\def\@opargbegintheorem#1#2#3{\@IEEEtmpitemindent\itemindent\relax +\topsep 0.2\@IEEEnormalsizeunitybaselineskip plus 0.26\@IEEEnormalsizeunitybaselineskip minus 0.05\@IEEEnormalsizeunitybaselineskip +\rmfamily\trivlist\hangindent\parindent% +% V1.6 The IEEE is back to using () around theorem names which are also in italics +% Thanks to Christian Peel for reporting this. + \item[]\textit{\bfseries\noindent #1\ #2\ (#3).} \itemindent\@IEEEtmpitemindent\relax} +% V1.7 remove bogus \unskip that caused equations in theorems to collide with +% lines below. +\def\@endtheorem{\endtrivlist\vskip 0.25\@IEEEnormalsizeunitybaselineskip plus 0.26\@IEEEnormalsizeunitybaselineskip minus 0.05\@IEEEnormalsizeunitybaselineskip} +\else +% +% noncompsoc +% +% V1.8 allow long theorem names to break across lines. +% Thanks to Miquel Payaro for reporting this. +\def\@begintheorem#1#2{\@IEEEtmpitemindent\itemindent\relax\topsep 0pt\rmfamily\trivlist% + \item[]\textit{\indent #1\ #2:} \itemindent\@IEEEtmpitemindent\relax} +\def\@opargbegintheorem#1#2#3{\@IEEEtmpitemindent\itemindent\relax\topsep 0pt\rmfamily \trivlist% +% V1.6 The IEEE is back to using () around theorem names which are also in italics +% Thanks to Christian Peel for reporting this. + \item[]\textit{\indent #1\ #2\ (#3):} \itemindent\@IEEEtmpitemindent\relax} +% V1.7 remove bogus \unskip that caused equations in theorems to collide with +% lines below. +\def\@endtheorem{\endtrivlist} +\fi + + + +% V1.6 +% display command for the section the theorem is in - so that \thesection +% is not used as this will be in Roman numerals when we want arabic. +% LaTeX2e uses \def\@thmcounter#1{\noexpand\arabic{#1}} for the theorem number +% (second part) display and \def\@thmcountersep{.} as a separator. +% V1.7 intercept calls to the section counter and reroute to \@IEEEthmcounterinsection +% to allow \appendix(ices} to override as needed. +% +% special handler for sections, allows appendix(ices) to override +\gdef\@IEEEthmcounterinsection#1{\arabic{#1}} +% string macro +\edef\@IEEEstringsection{section} + +% redefine the #1#2[#3] form of newtheorem to use a hook to \@IEEEthmcounterinsection +% if section in_counter is used +\def\@xnthm#1#2[#3]{% + \expandafter\@ifdefinable\csname #1\endcsname + {\@definecounter{#1}\@newctr{#1}[#3]% + \edef\@IEEEstringtmp{#3} + \ifx\@IEEEstringtmp\@IEEEstringsection + \expandafter\xdef\csname the#1\endcsname{% + \noexpand\@IEEEthmcounterinsection{#3}\@thmcountersep + \@thmcounter{#1}}% + \else + \expandafter\xdef\csname the#1\endcsname{% + \expandafter\noexpand\csname the#3\endcsname \@thmcountersep + \@thmcounter{#1}}% + \fi + \global\@namedef{#1}{\@thm{#1}{#2}}% + \global\@namedef{end#1}{\@endtheorem}}} + + + +%% SET UP THE DEFAULT PAGESTYLE +\pagestyle{headings} +\pagenumbering{arabic} + +% normally the page counter starts at 1 +\setcounter{page}{1} +% however, for peerreview the cover sheet is page 0 or page -1 +% (for duplex printing) +\ifCLASSOPTIONpeerreview + \if@twoside + \setcounter{page}{-1} + \else + \setcounter{page}{0} + \fi +\fi + +% standard book class behavior - let bottom line float up and down as +% needed when single sided +\ifCLASSOPTIONtwoside\else\raggedbottom\fi +% if two column - turn on twocolumn, allow word spacings to stretch more and +% enforce a rigid position for the last lines +\ifCLASSOPTIONtwocolumn +% the peer review option delays invoking twocolumn + \ifCLASSOPTIONpeerreview\else + \twocolumn + \fi +\sloppy +\flushbottom +\fi + + + + +% \APPENDIX and \APPENDICES definitions + +% This is the \@ifmtarg command from the LaTeX ifmtarg package +% by Peter Wilson (CUA) and Donald Arseneau +% \@ifmtarg is used to determine if an argument to a command +% is present or not. +% For instance: +% \@ifmtarg{#1}{\typeout{empty}}{\typeout{has something}} +% \@ifmtarg is used with our redefined \section command if +% \appendices is invoked. +% The command \section will behave slightly differently depending +% on whether the user specifies a title: +% \section{My appendix title} +% or not: +% \section{} +% This way, we can eliminate the blank lines where the title +% would be, and the unneeded : after Appendix in the table of +% contents +\begingroup +\catcode`\Q=3 +\long\gdef\@ifmtarg#1{\@xifmtarg#1QQ\@secondoftwo\@firstoftwo\@nil} +\long\gdef\@xifmtarg#1#2Q#3#4#5\@nil{#4} +\endgroup +% end of \@ifmtarg defs + + +% V1.7 +% command that allows the one time saving of the original definition +% of section to \@IEEEappendixsavesection for \appendix or \appendices +% we don't save \section here as it may be redefined later by other +% packages (hyperref.sty, etc.) +\def\@IEEEsaveoriginalsectiononce{\let\@IEEEappendixsavesection\section +\let\@IEEEsaveoriginalsectiononce\relax} + +% neat trick to grab and process the argument from \section{argument} +% we process differently if the user invoked \section{} with no +% argument (title) +% note we reroute the call to the old \section* +\def\@IEEEprocessthesectionargument#1{% +\@ifmtarg{#1}{% +\@IEEEappendixsavesection*{\appendixname\nobreakspace\thesectiondis}% +\addcontentsline{toc}{section}{\appendixname\nobreakspace\thesection}}{% +\@IEEEappendixsavesection*{\appendixname\nobreakspace\thesectiondis\\* #1}% +\addcontentsline{toc}{section}{\appendixname\nobreakspace\thesection: #1}}} + +% we use this if the user calls \section{} after +% \appendix-- which has no meaning. So, we ignore the +% command and its argument. Then, warn the user. +\def\@IEEEdestroythesectionargument#1{\typeout{** WARNING: Ignoring useless +\protect\section\space in Appendix (line \the\inputlineno).}} + + +% remember \thesection forms will be displayed in \ref calls +% and in the Table of Contents. +% The \sectiondis form is used in the actual heading itself + +% appendix command for one single appendix +% normally has no heading. However, if you want a +% heading, you can do so via the optional argument: +% \appendix[Optional Heading] +\def\appendix{\relax} +\renewcommand{\appendix}[1][]{\@IEEEsaveoriginalsectiononce\par + % v1.6 keep hyperref's identifiers unique + \gdef\theHsection{Appendix.A}% + % v1.6 adjust hyperref's string name for the section + \xdef\Hy@chapapp{appendix}% + \setcounter{section}{0}% + \setcounter{subsection}{0}% + \setcounter{subsubsection}{0}% + \setcounter{paragraph}{0}% + \gdef\thesection{A}% + \gdef\thesectiondis{}% + \gdef\thesubsection{\Alph{subsection}}% + \gdef\@IEEEthmcounterinsection##1{A} + \refstepcounter{section}% update the \ref counter + \@ifmtarg{#1}{\@IEEEappendixsavesection*{\appendixname}% + \addcontentsline{toc}{section}{\appendixname}}{% + \@IEEEappendixsavesection*{\appendixname\nobreakspace\\* #1}% + \addcontentsline{toc}{section}{\appendixname: #1}}% + % redefine \section command for appendix + % leave \section* as is + \def\section{\@ifstar{\@IEEEappendixsavesection*}{% + \@IEEEdestroythesectionargument}}% throw out the argument + % of the normal form +} + + + +% appendices command for multiple appendices +% user then calls \section with an argument (possibly empty) to +% declare the individual appendices +\def\appendices{\@IEEEsaveoriginalsectiononce\par + % v1.6 keep hyperref's identifiers unique + \gdef\theHsection{Appendix.\Alph{section}}% + % v1.6 adjust hyperref's string name for the section + \xdef\Hy@chapapp{appendix}% + \setcounter{section}{-1}% we want \refstepcounter to use section 0 + \setcounter{subsection}{0}% + \setcounter{subsubsection}{0}% + \setcounter{paragraph}{0}% + \ifCLASSOPTIONromanappendices% + \gdef\thesection{\Roman{section}}% + \gdef\thesectiondis{\Roman{section}}% + \@IEEEcompsocconfonly{\gdef\thesectiondis{\Roman{section}.}}% + \gdef\@IEEEthmcounterinsection##1{A\arabic{##1}} + \else% + \gdef\thesection{\Alph{section}}% + \gdef\thesectiondis{\Alph{section}}% + \@IEEEcompsocconfonly{\gdef\thesectiondis{\Alph{section}.}}% + \gdef\@IEEEthmcounterinsection##1{\Alph{##1}} + \fi% + \refstepcounter{section}% update the \ref counter + \setcounter{section}{0}% NEXT \section will be the FIRST appendix + % redefine \section command for appendices + % leave \section* as is + \def\section{\@ifstar{\@IEEEappendixsavesection*}{% process the *-form + \refstepcounter{section}% or is a new section so, + \@IEEEprocessthesectionargument}}% process the argument + % of the normal form +} + + + +% V1.7 compoc uses nonbold drop cap and small caps word style +\ifCLASSOPTIONcompsoc + \def\IEEEPARstartFONTSTYLE{\mdseries} + \def\IEEEPARstartWORDFONTSTYLE{\scshape} + \def\IEEEPARstartWORDCAPSTYLE{\relax} +\fi +% +% +% \IEEEPARstart +% Definition for the big two line drop cap letter at the beginning of the +% first paragraph of journal papers. The first argument is the first letter +% of the first word, the second argument is the remaining letters of the +% first word which will be rendered in upper case. +% In V1.6 this has been completely rewritten to: +% +% 1. no longer have problems when the user begins an environment +% within the paragraph that uses \IEEEPARstart. +% 2. auto-detect and use the current font family +% 3. revise handling of the space at the end of the first word so that +% interword glue will now work as normal. +% 4. produce correctly aligned edges for the (two) indented lines. +% +% We generalize things via control macros - playing with these is fun too. +% +% V1.7 added more control macros to make it easy for IEEEtrantools.sty users +% to change the font style. +% +% the number of lines that are indented to clear it +% may need to increase if using decenders +\providecommand{\IEEEPARstartDROPLINES}{2} +% minimum number of lines left on a page to allow a \@IEEEPARstart +% Does not take into consideration rubber shrink, so it tends to +% be overly cautious +\providecommand{\IEEEPARstartMINPAGELINES}{2} +% V1.7 the height of the drop cap is adjusted to match the height of this text +% in the current font (when \IEEEPARstart is called). +\providecommand{\IEEEPARstartHEIGHTTEXT}{T} +% the depth the letter is lowered below the baseline +% the height (and size) of the letter is determined by the sum +% of this value and the height of the \IEEEPARstartHEIGHTTEXT in the current +% font. It is a good idea to set this value in terms of the baselineskip +% so that it can respond to changes therein. +\providecommand{\IEEEPARstartDROPDEPTH}{1.1\baselineskip} +% V1.7 the font the drop cap will be rendered in, +% can take zero or one argument. +\providecommand{\IEEEPARstartFONTSTYLE}{\bfseries} +% V1.7 any additional, non-font related commands needed to modify +% the drop cap letter, can take zero or one argument. +\providecommand{\IEEEPARstartCAPSTYLE}{\MakeUppercase} +% V1.7 the font that will be used to render the rest of the word, +% can take zero or one argument. +\providecommand{\IEEEPARstartWORDFONTSTYLE}{\relax} +% V1.7 any additional, non-font related commands needed to modify +% the rest of the word, can take zero or one argument. +\providecommand{\IEEEPARstartWORDCAPSTYLE}{\MakeUppercase} +% This is the horizontal separation distance from the drop letter to the main text. +% Lengths that depend on the font (e.g., ex, em, etc.) will be referenced +% to the font that is active when \IEEEPARstart is called. +\providecommand{\IEEEPARstartSEP}{0.15em} +% V1.7 horizontal offset applied to the left of the drop cap. +\providecommand{\IEEEPARstartHOFFSET}{0em} +% V1.7 Italic correction command applied at the end of the drop cap. +\providecommand{\IEEEPARstartITLCORRECT}{\/} + +% width of the letter output, set globally. Can be used in \IEEEPARstartSEP +% or \IEEEPARstartHOFFSET, but not the height lengths. +\newdimen\IEEEPARstartletwidth +\IEEEPARstartletwidth 0pt\relax + +% definition of \IEEEPARstart +% THIS IS A CONTROLLED SPACING AREA, DO NOT ALLOW SPACES WITHIN THESE LINES +% +% The token \@IEEEPARstartfont will be globally defined after the first use +% of \IEEEPARstart and will be a font command which creates the big letter +% The first argument is the first letter of the first word and the second +% argument is the rest of the first word(s). +\def\IEEEPARstart#1#2{\par{% +% if this page does not have enough space, break it and lets start +% on a new one +\@IEEEtranneedspace{\IEEEPARstartMINPAGELINES\baselineskip}{\relax}% +% V1.7 move this up here in case user uses \textbf for \IEEEPARstartFONTSTYLE +% which uses command \leavevmode which causes an unwanted \indent to be issued +\noindent +% calculate the desired height of the big letter +% it extends from the top of \IEEEPARstartHEIGHTTEXT in the current font +% down to \IEEEPARstartDROPDEPTH below the current baseline +\settoheight{\@IEEEtrantmpdimenA}{\IEEEPARstartHEIGHTTEXT}% +\addtolength{\@IEEEtrantmpdimenA}{\IEEEPARstartDROPDEPTH}% +% extract the name of the current font in bold +% and place it in \@IEEEPARstartFONTNAME +\def\@IEEEPARstartGETFIRSTWORD##1 ##2\relax{##1}% +{\IEEEPARstartFONTSTYLE{\selectfont\edef\@IEEEPARstartFONTNAMESPACE{\fontname\font\space}% +\xdef\@IEEEPARstartFONTNAME{\expandafter\@IEEEPARstartGETFIRSTWORD\@IEEEPARstartFONTNAMESPACE\relax}}}% +% define a font based on this name with a point size equal to the desired +% height of the drop letter +\font\@IEEEPARstartsubfont\@IEEEPARstartFONTNAME\space at \@IEEEtrantmpdimenA\relax% +% save this value as a counter (integer) value (sp points) +\@IEEEtrantmpcountA=\@IEEEtrantmpdimenA% +% now get the height of the actual letter produced by this font size +\settoheight{\@IEEEtrantmpdimenB}{\@IEEEPARstartsubfont\IEEEPARstartCAPSTYLE{#1}}% +% If something bogus happens like the first argument is empty or the +% current font is strange, do not allow a zero height. +\ifdim\@IEEEtrantmpdimenB=0pt\relax% +\typeout{** WARNING: IEEEPARstart drop letter has zero height! (line \the\inputlineno)}% +\typeout{ Forcing the drop letter font size to 10pt.}% +\@IEEEtrantmpdimenB=10pt% +\fi% +% and store it as a counter +\@IEEEtrantmpcountB=\@IEEEtrantmpdimenB% +% Since a font size doesn't exactly correspond to the height of the capital +% letters in that font, the actual height of the letter, \@IEEEtrantmpcountB, +% will be less than that desired, \@IEEEtrantmpcountA +% we need to raise the font size, \@IEEEtrantmpdimenA +% by \@IEEEtrantmpcountA / \@IEEEtrantmpcountB +% But, TeX doesn't have floating point division, so we have to use integer +% division. Hence the use of the counters. +% We need to reduce the denominator so that the loss of the remainder will +% have minimal affect on the accuracy of the result +\divide\@IEEEtrantmpcountB by 200% +\divide\@IEEEtrantmpcountA by \@IEEEtrantmpcountB% +% Then reequalize things when we use TeX's ability to multiply by +% floating point values +\@IEEEtrantmpdimenB=0.005\@IEEEtrantmpdimenA% +\multiply\@IEEEtrantmpdimenB by \@IEEEtrantmpcountA% +% \@IEEEPARstartfont is globaly set to the calculated font of the big letter +% We need to carry this out of the local calculation area to to create the +% big letter. +\global\font\@IEEEPARstartfont\@IEEEPARstartFONTNAME\space at \@IEEEtrantmpdimenB% +% Now set \@IEEEtrantmpdimenA to the width of the big letter +% We need to carry this out of the local calculation area to set the +% hanging indent +\settowidth{\global\@IEEEtrantmpdimenA}{\@IEEEPARstartfont +\IEEEPARstartCAPSTYLE{#1\IEEEPARstartITLCORRECT}}}% +% end of the isolated calculation environment +\global\IEEEPARstartletwidth\@IEEEtrantmpdimenA\relax% +% add in the extra clearance we want +\advance\@IEEEtrantmpdimenA by \IEEEPARstartSEP\relax% +% add in the optional offset +\advance\@IEEEtrantmpdimenA by \IEEEPARstartHOFFSET\relax% +% V1.7 don't allow negative offsets to produce negative hanging indents +\@IEEEtrantmpdimenB\@IEEEtrantmpdimenA +\ifnum\@IEEEtrantmpdimenB < 0 \@IEEEtrantmpdimenB 0pt\fi +% \@IEEEtrantmpdimenA has the width of the big letter plus the +% separation space and \@IEEEPARstartfont is the font we need to use +% Now, we make the letter and issue the hanging indent command +% The letter is placed in a box of zero width and height so that other +% text won't be displaced by it. +\hangindent\@IEEEtrantmpdimenB\hangafter=-\IEEEPARstartDROPLINES% +\makebox[0pt][l]{\hspace{-\@IEEEtrantmpdimenA}% +\raisebox{-\IEEEPARstartDROPDEPTH}[0pt][0pt]{\hspace{\IEEEPARstartHOFFSET}% +\@IEEEPARstartfont\IEEEPARstartCAPSTYLE{#1\IEEEPARstartITLCORRECT}% +\hspace{\IEEEPARstartSEP}}}% +{\IEEEPARstartWORDFONTSTYLE{\IEEEPARstartWORDCAPSTYLE{\selectfont#2}}}} + + + + +% determines if the space remaining on a given page is equal to or greater +% than the specified space of argument one +% if not, execute argument two (only if the remaining space is greater than zero) +% and issue a \newpage +% +% example: \@IEEEtranneedspace{2in}{\vfill} +% +% Does not take into consideration rubber shrinkage, so it tends to +% be overly cautious +% Based on an example posted by Donald Arseneau +% Note this macro uses \@IEEEtrantmpdimenB internally for calculations, +% so DO NOT PASS \@IEEEtrantmpdimenB to this routine +% if you need a dimen register, import with \@IEEEtrantmpdimenA instead +\def\@IEEEtranneedspace#1#2{\penalty-100\begingroup%shield temp variable +\@IEEEtrantmpdimenB\pagegoal\advance\@IEEEtrantmpdimenB-\pagetotal% space left +\ifdim #1>\@IEEEtrantmpdimenB\relax% not enough space left +\ifdim\@IEEEtrantmpdimenB>\z@\relax #2\fi% +\newpage% +\fi\endgroup} + + + +% IEEEbiography ENVIRONMENT +% Allows user to enter biography leaving place for picture (adapts to font size) +% As of V1.5, a new optional argument allows you to have a real graphic! +% V1.5 and later also fixes the "colliding biographies" which could happen when a +% biography's text was shorter than the space for the photo. +% MDS 7/2001 +% V1.6 prevent multiple biographies from making multiple TOC entries +\newif\if@IEEEbiographyTOCentrynotmade +\global\@IEEEbiographyTOCentrynotmadetrue + +% biography counter so hyperref can jump directly to the biographies +% and not just the previous section +\newcounter{IEEEbiography} +\setcounter{IEEEbiography}{0} + +% photo area size +\def\@IEEEBIOphotowidth{1.0in} % width of the biography photo area +\def\@IEEEBIOphotodepth{1.25in} % depth (height) of the biography photo area +% area cleared for photo +\def\@IEEEBIOhangwidth{1.14in} % width cleared for the biography photo area +\def\@IEEEBIOhangdepth{1.25in} % depth cleared for the biography photo area + % actual depth will be a multiple of + % \baselineskip, rounded up +\def\@IEEEBIOskipN{4\baselineskip}% nominal value of the vskip above the biography + +\newenvironment{IEEEbiography}[2][]{\normalfont\@IEEEcompsoconly{\sffamily}\footnotesize% +\unitlength 1in\parskip=0pt\par\parindent 1em\interlinepenalty500% +% we need enough space to support the hanging indent +% the nominal value of the spacer +% and one extra line for good measure +\@IEEEtrantmpdimenA=\@IEEEBIOhangdepth% +\advance\@IEEEtrantmpdimenA by \@IEEEBIOskipN% +\advance\@IEEEtrantmpdimenA by 1\baselineskip% +% if this page does not have enough space, break it and lets start +% with a new one +\@IEEEtranneedspace{\@IEEEtrantmpdimenA}{\relax}% +% nominal spacer can strech, not shrink use 1fil so user can out stretch with \vfill +\vskip \@IEEEBIOskipN plus 1fil minus 0\baselineskip% +% the default box for where the photo goes +\def\@IEEEtempbiographybox{{\setlength{\fboxsep}{0pt}\framebox{% +\begin{minipage}[b][\@IEEEBIOphotodepth][c]{\@IEEEBIOphotowidth}\centering PLACE\\ PHOTO\\ HERE \end{minipage}}}}% +% +% detect if the optional argument was supplied, this requires the +% \@ifmtarg command as defined in the appendix section above +% and if so, override the default box with what they want +\@ifmtarg{#1}{\relax}{\def\@IEEEtempbiographybox{\mbox{\begin{minipage}[b][\@IEEEBIOphotodepth][c]{\@IEEEBIOphotowidth}% +\centering% +#1% +\end{minipage}}}}% end if optional argument supplied +% Make an entry into the table of contents only if we have not done so before +\if@IEEEbiographyTOCentrynotmade% +% link labels to the biography counter so hyperref will jump +% to the biography, not the previous section +\setcounter{IEEEbiography}{-1}% +\refstepcounter{IEEEbiography}% +\addcontentsline{toc}{section}{Biographies}% +\global\@IEEEbiographyTOCentrynotmadefalse% +\fi% +% one more biography +\refstepcounter{IEEEbiography}% +% Make an entry for this name into the table of contents +\addcontentsline{toc}{subsection}{#2}% +% V1.6 properly handle if a new paragraph should occur while the +% hanging indent is still active. Do this by redefining \par so +% that it will not start a new paragraph. (But it will appear to the +% user as if it did.) Also, strip any leading pars, newlines, or spaces. +\let\@IEEEBIOORGparCMD=\par% save the original \par command +\edef\par{\hfil\break\indent}% the new \par will not be a "real" \par +\settoheight{\@IEEEtrantmpdimenA}{\@IEEEtempbiographybox}% get height of biography box +\@IEEEtrantmpdimenB=\@IEEEBIOhangdepth% +\@IEEEtrantmpcountA=\@IEEEtrantmpdimenB% countA has the hang depth +\divide\@IEEEtrantmpcountA by \baselineskip% calculates lines needed to produce the hang depth +\advance\@IEEEtrantmpcountA by 1% ensure we overestimate +% set the hanging indent +\hangindent\@IEEEBIOhangwidth% +\hangafter-\@IEEEtrantmpcountA% +% reference the top of the photo area to the top of a capital T +\settoheight{\@IEEEtrantmpdimenB}{\mbox{T}}% +% set the photo box, give it zero width and height so as not to disturb anything +\noindent\makebox[0pt][l]{\hspace{-\@IEEEBIOhangwidth}\raisebox{\@IEEEtrantmpdimenB}[0pt][0pt]{% +\raisebox{-\@IEEEBIOphotodepth}[0pt][0pt]{\@IEEEtempbiographybox}}}% +% now place the author name and begin the bio text +\noindent\textbf{#2\ }\@IEEEgobbleleadPARNLSP}{\relax\let\par=\@IEEEBIOORGparCMD\par% +% 7/2001 V1.5 detect when the biography text is shorter than the photo area +% and pad the unused area - preventing a collision from the next biography entry +% MDS +\ifnum \prevgraf <\@IEEEtrantmpcountA\relax% detect when the biography text is shorter than the photo + \advance\@IEEEtrantmpcountA by -\prevgraf% calculate how many lines we need to pad + \advance\@IEEEtrantmpcountA by -1\relax% we compensate for the fact that we indented an extra line + \@IEEEtrantmpdimenA=\baselineskip% calculate the length of the padding + \multiply\@IEEEtrantmpdimenA by \@IEEEtrantmpcountA% + \noindent\rule{0pt}{\@IEEEtrantmpdimenA}% insert an invisible support strut +\fi% +\par\normalfont} + + + +% V1.6 +% added biography without a photo environment +\newenvironment{IEEEbiographynophoto}[1]{% +% Make an entry into the table of contents only if we have not done so before +\if@IEEEbiographyTOCentrynotmade% +% link labels to the biography counter so hyperref will jump +% to the biography, not the previous section +\setcounter{IEEEbiography}{-1}% +\refstepcounter{IEEEbiography}% +\addcontentsline{toc}{section}{Biographies}% +\global\@IEEEbiographyTOCentrynotmadefalse% +\fi% +% one more biography +\refstepcounter{IEEEbiography}% +% Make an entry for this name into the table of contents +\addcontentsline{toc}{subsection}{#1}% +\normalfont\@IEEEcompsoconly{\sffamily}\footnotesize\interlinepenalty500% +\vskip 4\baselineskip plus 1fil minus 0\baselineskip% +\parskip=0pt\par% +\noindent\textbf{#1\ }\@IEEEgobbleleadPARNLSP}{\relax\par\normalfont} + + +% provide the user with some old font commands +% got this from article.cls +\DeclareOldFontCommand{\rm}{\normalfont\rmfamily}{\mathrm} +\DeclareOldFontCommand{\sf}{\normalfont\sffamily}{\mathsf} +\DeclareOldFontCommand{\tt}{\normalfont\ttfamily}{\mathtt} +\DeclareOldFontCommand{\bf}{\normalfont\bfseries}{\mathbf} +\DeclareOldFontCommand{\it}{\normalfont\itshape}{\mathit} +\DeclareOldFontCommand{\sl}{\normalfont\slshape}{\@nomath\sl} +\DeclareOldFontCommand{\sc}{\normalfont\scshape}{\@nomath\sc} +\DeclareRobustCommand*\cal{\@fontswitch\relax\mathcal} +\DeclareRobustCommand*\mit{\@fontswitch\relax\mathnormal} + + +% SPECIAL PAPER NOTICE COMMANDS +% +% holds the special notice text +\def\@IEEEspecialpapernotice{\relax} + +% for special papers, like invited papers, the user can do: +% \IEEEspecialpapernotice{(Invited Paper)} before \maketitle +\def\IEEEspecialpapernotice#1{\ifCLASSOPTIONconference% +\def\@IEEEspecialpapernotice{{\sublargesize\textit{#1}\vspace*{1em}}}% +\else% +\def\@IEEEspecialpapernotice{{\\*[1.5ex]\sublargesize\textit{#1}}\vspace*{-2ex}}% +\fi} + + + + +% PUBLISHER ID COMMANDS +% to insert a publisher's ID footer +% V1.6 \IEEEpubid has been changed so that the change in page size and style +% occurs in \maketitle. \IEEEpubid must now be issued prior to \maketitle +% use \IEEEpubidadjcol as before - in the second column of the title page +% These changes allow \maketitle to take the reduced page height into +% consideration when dynamically setting the space between the author +% names and the maintext. +% +% the amount the main text is pulled up to make room for the +% publisher's ID footer +% The IEEE uses about 1.3\baselineskip for journals, +% dynamic title spacing will clean up the fraction +\def\@IEEEpubidpullup{1.3\baselineskip} +\ifCLASSOPTIONtechnote +% for technotes it must be an integer of baselineskip as there can be no +% dynamic title spacing for two column mode technotes (the title is in the +% in first column) and we should maintain an integer number of lines in the +% second column +% There are some examples (such as older issues of "Transactions on +% Information Theory") in which the IEEE really pulls the text off the ID for +% technotes - about 0.55in (or 4\baselineskip). We'll use 2\baselineskip +% and call it even. +\def\@IEEEpubidpullup{2\baselineskip} +\fi + +% V1.7 compsoc does not use a pullup +\ifCLASSOPTIONcompsoc +\def\@IEEEpubidpullup{0pt} +\fi + +% holds the ID text +\def\@IEEEpubid{\relax} + +% flag so \maketitle can tell if \IEEEpubid was called +\newif\if@IEEEusingpubid +\global\@IEEEusingpubidfalse +% issue this command in the page to have the ID at the bottom +% V1.6 use before \maketitle +\def\IEEEpubid#1{\def\@IEEEpubid{#1}\global\@IEEEusingpubidtrue} + + +% command which will pull up (shorten) the column it is executed in +% to make room for the publisher ID. Place in the second column of +% the title page when using \IEEEpubid +% Is smart enough not to do anything when in single column text or +% if the user hasn't called \IEEEpubid +% currently needed in for the second column of a page with the +% publisher ID. If not needed in future releases, please provide this +% command and define it as \relax for backward compatibility +% v1.6b do not allow command to operate if the peer review option has been +% selected because \IEEEpubidadjcol will not be on the cover page. +% V1.7 do nothing if compsoc +\def\IEEEpubidadjcol{\ifCLASSOPTIONcompsoc\else\ifCLASSOPTIONpeerreview\else +\if@twocolumn\if@IEEEusingpubid\enlargethispage{-\@IEEEpubidpullup}\fi\fi\fi\fi} + +% Special thanks to Peter Wilson, Daniel Luecking, and the other +% gurus at comp.text.tex, for helping me to understand how best to +% implement the IEEEpubid command in LaTeX. + + + +%% Lockout some commands under various conditions + +% general purpose bit bucket +\newsavebox{\@IEEEtranrubishbin} + +% flags to prevent multiple warning messages +\newif\if@IEEEWARNthanks +\newif\if@IEEEWARNIEEEPARstart +\newif\if@IEEEWARNIEEEbiography +\newif\if@IEEEWARNIEEEbiographynophoto +\newif\if@IEEEWARNIEEEpubid +\newif\if@IEEEWARNIEEEpubidadjcol +\newif\if@IEEEWARNIEEEmembership +\newif\if@IEEEWARNIEEEaftertitletext +\@IEEEWARNthankstrue +\@IEEEWARNIEEEPARstarttrue +\@IEEEWARNIEEEbiographytrue +\@IEEEWARNIEEEbiographynophototrue +\@IEEEWARNIEEEpubidtrue +\@IEEEWARNIEEEpubidadjcoltrue +\@IEEEWARNIEEEmembershiptrue +\@IEEEWARNIEEEaftertitletexttrue + + +%% Lockout some commands when in various modes, but allow them to be restored if needed +%% +% save commands which might be locked out +% so that the user can later restore them if needed +\let\@IEEESAVECMDthanks\thanks +\let\@IEEESAVECMDIEEEPARstart\IEEEPARstart +\let\@IEEESAVECMDIEEEbiography\IEEEbiography +\let\@IEEESAVECMDendIEEEbiography\endIEEEbiography +\let\@IEEESAVECMDIEEEbiographynophoto\IEEEbiographynophoto +\let\@IEEESAVECMDendIEEEbiographynophoto\endIEEEbiographynophoto +\let\@IEEESAVECMDIEEEpubid\IEEEpubid +\let\@IEEESAVECMDIEEEpubidadjcol\IEEEpubidadjcol +\let\@IEEESAVECMDIEEEmembership\IEEEmembership +\let\@IEEESAVECMDIEEEaftertitletext\IEEEaftertitletext + + +% disable \IEEEPARstart when in draft mode +% This may have originally been done because the pre-V1.6 drop letter +% algorithm had problems with a non-unity baselinestretch +% At any rate, it seems too formal to have a drop letter in a draft +% paper. +\ifCLASSOPTIONdraftcls +\def\IEEEPARstart#1#2{#1#2\if@IEEEWARNIEEEPARstart\typeout{** ATTENTION: \noexpand\IEEEPARstart + is disabled in draft mode (line \the\inputlineno).}\fi\global\@IEEEWARNIEEEPARstartfalse} +\fi +% and for technotes +\ifCLASSOPTIONtechnote +\def\IEEEPARstart#1#2{#1#2\if@IEEEWARNIEEEPARstart\typeout{** WARNING: \noexpand\IEEEPARstart + is locked out for technotes (line \the\inputlineno).}\fi\global\@IEEEWARNIEEEPARstartfalse} +\fi + + +% lockout unneeded commands when in conference mode +\ifCLASSOPTIONconference +% when locked out, \thanks, \IEEEbiography, \IEEEbiographynophoto, \IEEEpubid, +% \IEEEmembership and \IEEEaftertitletext will all swallow their given text. +% \IEEEPARstart will output a normal character instead +% warn the user about these commands only once to prevent the console screen +% from filling up with redundant messages +\def\thanks#1{\if@IEEEWARNthanks\typeout{** WARNING: \noexpand\thanks + is locked out when in conference mode (line \the\inputlineno).}\fi\global\@IEEEWARNthanksfalse} +\def\IEEEPARstart#1#2{#1#2\if@IEEEWARNIEEEPARstart\typeout{** WARNING: \noexpand\IEEEPARstart + is locked out when in conference mode (line \the\inputlineno).}\fi\global\@IEEEWARNIEEEPARstartfalse} + + +% LaTeX treats environments and commands with optional arguments differently. +% the actual ("internal") command is stored as \\commandname +% (accessed via \csname\string\commandname\endcsname ) +% the "external" command \commandname is a macro with code to determine +% whether or not the optional argument is presented and to provide the +% default if it is absent. So, in order to save and restore such a command +% we would have to save and restore \\commandname as well. But, if LaTeX +% ever changes the way it names the internal names, the trick would break. +% Instead let us just define a new environment so that the internal +% name can be left undisturbed. +\newenvironment{@IEEEbogusbiography}[2][]{\if@IEEEWARNIEEEbiography\typeout{** WARNING: \noexpand\IEEEbiography + is locked out when in conference mode (line \the\inputlineno).}\fi\global\@IEEEWARNIEEEbiographyfalse% +\setbox\@IEEEtranrubishbin\vbox\bgroup}{\egroup\relax} +% and make biography point to our bogus biography +\let\IEEEbiography=\@IEEEbogusbiography +\let\endIEEEbiography=\end@IEEEbogusbiography + +\renewenvironment{IEEEbiographynophoto}[1]{\if@IEEEWARNIEEEbiographynophoto\typeout{** WARNING: \noexpand\IEEEbiographynophoto + is locked out when in conference mode (line \the\inputlineno).}\fi\global\@IEEEWARNIEEEbiographynophotofalse% +\setbox\@IEEEtranrubishbin\vbox\bgroup}{\egroup\relax} + +\def\IEEEpubid#1{\if@IEEEWARNIEEEpubid\typeout{** WARNING: \noexpand\IEEEpubid + is locked out when in conference mode (line \the\inputlineno).}\fi\global\@IEEEWARNIEEEpubidfalse} +\def\IEEEpubidadjcol{\if@IEEEWARNIEEEpubidadjcol\typeout{** WARNING: \noexpand\IEEEpubidadjcol + is locked out when in conference mode (line \the\inputlineno).}\fi\global\@IEEEWARNIEEEpubidadjcolfalse} +\def\IEEEmembership#1{\if@IEEEWARNIEEEmembership\typeout{** WARNING: \noexpand\IEEEmembership + is locked out when in conference mode (line \the\inputlineno).}\fi\global\@IEEEWARNIEEEmembershipfalse} +\def\IEEEaftertitletext#1{\if@IEEEWARNIEEEaftertitletext\typeout{** WARNING: \noexpand\IEEEaftertitletext + is locked out when in conference mode (line \the\inputlineno).}\fi\global\@IEEEWARNIEEEaftertitletextfalse} +\fi + + +% provide a way to restore the commands that are locked out +\def\IEEEoverridecommandlockouts{% +\typeout{** ATTENTION: Overriding command lockouts (line \the\inputlineno).}% +\let\thanks\@IEEESAVECMDthanks% +\let\IEEEPARstart\@IEEESAVECMDIEEEPARstart% +\let\IEEEbiography\@IEEESAVECMDIEEEbiography% +\let\endIEEEbiography\@IEEESAVECMDendIEEEbiography% +\let\IEEEbiographynophoto\@IEEESAVECMDIEEEbiographynophoto% +\let\endIEEEbiographynophoto\@IEEESAVECMDendIEEEbiographynophoto% +\let\IEEEpubid\@IEEESAVECMDIEEEpubid% +\let\IEEEpubidadjcol\@IEEESAVECMDIEEEpubidadjcol% +\let\IEEEmembership\@IEEESAVECMDIEEEmembership% +\let\IEEEaftertitletext\@IEEESAVECMDIEEEaftertitletext} + + + +% need a backslash character for typeout output +{\catcode`\|=0 \catcode`\\=12 +|xdef|@IEEEbackslash{\}} + + +% hook to allow easy disabling of all legacy warnings +\def\@IEEElegacywarn#1#2{\typeout{** ATTENTION: \@IEEEbackslash #1 is deprecated (line \the\inputlineno). +Use \@IEEEbackslash #2 instead.}} + + +% provide some legacy IEEEtran commands +\def\IEEEcompsoctitleabstractindextext{\@IEEElegacywarn{IEEEcompsoctitleabstractindextext}{IEEEtitleabstractindextext}\IEEEtitleabstractindextext} +\def\IEEEdisplaynotcompsoctitleabstractindextext{\@IEEElegacywarn{IEEEdisplaynotcompsoctitleabstractindextext}{IEEEdisplaynontitleabstractindextext}\IEEEdisplaynontitleabstractindextext} +% provide some legacy IEEEtran environments + + +% V1.8a no more support for these legacy commands +%\def\authorblockA{\@IEEElegacywarn{authorblockA}{IEEEauthorblockA}\IEEEauthorblockA} +%\def\authorblockN{\@IEEElegacywarn{authorblockN}{IEEEauthorblockN}\IEEEauthorblockN} +%\def\authorrefmark{\@IEEElegacywarn{authorrefmark}{IEEEauthorrefmark}\IEEEauthorrefmark} +%\def\PARstart{\@IEEElegacywarn{PARstart}{IEEEPARstart}\IEEEPARstart} +%\def\pubid{\@IEEElegacywarn{pubid}{IEEEpubid}\IEEEpubid} +%\def\pubidadjcol{\@IEEElegacywarn{pubidadjcol}{IEEEpubidadjcol}\IEEEpubidadjcol} +%\def\specialpapernotice{\@IEEElegacywarn{specialpapernotice}{IEEEspecialpapernotice}\IEEEspecialpapernotice} +% and environments +%\def\keywords{\@IEEElegacywarn{keywords}{IEEEkeywords}\IEEEkeywords} +%\def\endkeywords{\endIEEEkeywords} +% V1.8 no more support for legacy IED list commands +%\let\labelindent\IEEElabelindent +%\def\calcleftmargin{\@IEEElegacywarn{calcleftmargin}{IEEEcalcleftmargin}\IEEEcalcleftmargin} +%\def\setlabelwidth{\@IEEElegacywarn{setlabelwidth}{IEEEsetlabelwidth}\IEEEsetlabelwidth} +%\def\usemathlabelsep{\@IEEElegacywarn{usemathlabelsep}{IEEEusemathlabelsep}\IEEEusemathlabelsep} +%\def\iedlabeljustifyc{\@IEEElegacywarn{iedlabeljustifyc}{IEEEiedlabeljustifyc}\IEEEiedlabeljustifyc} +%\def\iedlabeljustifyl{\@IEEElegacywarn{iedlabeljustifyl}{IEEEiedlabeljustifyl}\IEEEiedlabeljustifyl} +%\def\iedlabeljustifyr{\@IEEElegacywarn{iedlabeljustifyr}{IEEEiedlabeljustifyr}\IEEEiedlabeljustifyr} +% V1.8 no more support for QED and proof stuff +%\def\QED{\@IEEElegacywarn{QED}{IEEEQED}\IEEEQED} +%\def\QEDclosed{\@IEEElegacywarn{QEDclosed}{IEEEQEDclosed}\IEEEQEDclosed} +%\def\QEDopen{\@IEEElegacywarn{QEDopen}{IEEEQEDopen}\IEEEQEDopen} +%\AtBeginDocument{\def\proof{\@IEEElegacywarn{proof}{IEEEproof}\IEEEproof}\def\endproof{\endIEEEproof}} +% V1.8 no longer support biography or biographynophoto +%\def\biography{\@IEEElegacywarn{biography}{IEEEbiography}\IEEEbiography} +%\def\biographynophoto{\@IEEElegacywarn{biographynophoto}{IEEEbiographynophoto}\IEEEbiographynophoto} +%\def\endbiography{\endIEEEbiography} +%\def\endbiographynophoto{\endIEEEbiographynophoto} +% V1.7 and later no longer supports \overrideIEEEmargins +%\def\overrideIEEEmargins{% +%\typeout{** WARNING: \string\overrideIEEEmargins \space no longer supported (line \the\inputlineno).}% +%\typeout{** Use the \string\CLASSINPUTinnersidemargin, \string\CLASSINPUToutersidemargin \space controls instead.}} + +\endinput + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%% End of IEEEtran.cls %%%%%%%%%%%%%%%%%%%%%%%%%%%% +% That's all folks! + diff --git a/OSU Coursework/CS 444 - Operating Systems II/Kernel Assignments/Project 1/IEEEtranN.bst b/OSU Coursework/CS 444 - Operating Systems II/Kernel Assignments/Project 1/IEEEtranN.bst new file mode 100644 index 0000000..7204eaf --- /dev/null +++ b/OSU Coursework/CS 444 - Operating Systems II/Kernel Assignments/Project 1/IEEEtranN.bst @@ -0,0 +1,2735 @@ +%% +%% IEEEtranN.bst +%% BibTeX Bibliography Style file +%% Natbib version of IEEEtran.bst +%% *** Not for normal IEEE work *** +%% Version 1.14 (2015/08/26) +%% +%% Copyright (c) 2003-2015 Michael Shell +%% +%% Original starting code base and algorithms obtained from the output of +%% Patrick W. Daly's makebst package as well as from prior versions of +%% IEEE BibTeX styles: +%% +%% 1. Howard Trickey and Oren Patashnik's ieeetr.bst (1985/1988) +%% 2. Silvano Balemi and Richard H. Roy's IEEEbib.bst (1993) +%% +%% Added sorting and natbib code is from Patrick W Daly's unsrtnat.bst +%% +%% +%% Support sites: +%% http://www.michaelshell.org/tex/ieeetran/ +%% http://www.ctan.org/pkg/ieeetran +%% and/or +%% http://www.ieee.org/ +%% +%% For use with BibTeX version 0.99a or later +%% +%% This is a natbib compatible citation style. +%% +%%************************************************************************* +%% Legal Notice: +%% This code is offered as-is without any warranty either expressed or +%% implied; without even the implied warranty of MERCHANTABILITY or +%% FITNESS FOR A PARTICULAR PURPOSE! +%% User assumes all risk. +%% In no event shall the IEEE or any contributor to this code be liable for +%% any damages or losses, including, but not limited to, incidental, +%% consequential, or any other damages, resulting from the use or misuse +%% of any information contained here. +%% +%% All comments are the opinions of their respective authors and are not +%% necessarily endorsed by the IEEE. +%% +%% This work is distributed under the LaTeX Project Public License (LPPL) +%% ( http://www.latex-project.org/ ) version 1.3, and may be freely used, +%% distributed and modified. A copy of the LPPL, version 1.3, is included +%% in the base LaTeX documentation of all distributions of LaTeX released +%% 2003/12/01 or later. +%% Retain all contribution notices and credits. +%% ** Modified files should be clearly indicated as such, including ** +%% ** renaming them and changing author support contact information. ** +%%************************************************************************* + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% DEFAULTS FOR THE CONTROLS OF THE BST STYLE %% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% These are the defaults for the user adjustable controls. The values used +% here can be overridden by the user via IEEEtranBSTCTL entry type. + +% NOTE: The recommended LaTeX command to invoke a control entry type is: +% +%\makeatletter +%\def\bstctlcite{\@ifnextchar[{\@bstctlcite}{\@bstctlcite[@auxout]}} +%\def\@bstctlcite[#1]#2{\@bsphack +% \@for\@citeb:=#2\do{% +% \edef\@citeb{\expandafter\@firstofone\@citeb}% +% \if@filesw\immediate\write\csname #1\endcsname{\string\citation{\@citeb}}\fi}% +% \@esphack} +%\makeatother +% +% It is called at the start of the document, before the first \cite, like: +% \bstctlcite{IEEEexample:BSTcontrol} +% +% IEEEtran.cls V1.6 and later does provide this command. + + + +% #0 turns off the display of the number for articles. +% #1 enables +FUNCTION {default.is.use.number.for.article} { #1 } + + +% #0 turns off the display of the paper and type fields in @inproceedings. +% #1 enables +FUNCTION {default.is.use.paper} { #1 } + + +% #0 turns off the display of urls +% #1 enables +FUNCTION {default.is.use.url} { #1 } + + +% #0 turns off the forced use of "et al." +% #1 enables +FUNCTION {default.is.forced.et.al} { #0 } + + +% The maximum number of names that can be present beyond which an "et al." +% usage is forced. Be sure that num.names.shown.with.forced.et.al (below) +% is not greater than this value! +% Note: There are many instances of references in IEEE journals which have +% a very large number of authors as well as instances in which "et al." is +% used profusely. +FUNCTION {default.max.num.names.before.forced.et.al} { #10 } + + +% The number of names that will be shown with a forced "et al.". +% Must be less than or equal to max.num.names.before.forced.et.al +FUNCTION {default.num.names.shown.with.forced.et.al} { #1 } + + +% #0 turns off the alternate interword spacing for entries with URLs. +% #1 enables +FUNCTION {default.is.use.alt.interword.spacing} { #1 } + + +% If alternate interword spacing for entries with URLs is enabled, this is +% the interword spacing stretch factor that will be used. For example, the +% default "4" here means that the interword spacing in entries with URLs can +% stretch to four times normal. Does not have to be an integer. Note that +% the value specified here can be overridden by the user in their LaTeX +% code via a command such as: +% "\providecommand\BIBentryALTinterwordstretchfactor{1.5}" in addition to +% that via the IEEEtranBSTCTL entry type. +FUNCTION {default.ALTinterwordstretchfactor} { "4" } + + +% #0 turns off the "dashification" of repeated (i.e., identical to those +% of the previous entry) names. The IEEE normally does this. +% #1 enables +FUNCTION {default.is.dash.repeated.names} { #1 } + + +% The default name format control string. +FUNCTION {default.name.format.string}{ "{f.~}{vv~}{ll}{, jj}" } + + +% The default LaTeX font command for the names. +FUNCTION {default.name.latex.cmd}{ "" } + + +% The default URL prefix. +FUNCTION {default.name.url.prefix}{ "[Online]. Available:" } + + +% Other controls that cannot be accessed via IEEEtranBSTCTL entry type. + +% #0 turns off the terminal startup banner/completed message so as to +% operate more quietly. +% #1 enables +FUNCTION {is.print.banners.to.terminal} { #1 } + + + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% FILE VERSION AND BANNER %% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +FUNCTION{bst.file.version} { "1.14" } +FUNCTION{bst.file.date} { "2015/08/26" } +FUNCTION{bst.file.website} { "http://www.michaelshell.org/tex/ieeetran/bibtex/" } + +FUNCTION {banner.message} +{ is.print.banners.to.terminal + { "-- IEEEtranN.bst version" " " * bst.file.version * + " (" * bst.file.date * ") " * "by Michael Shell." * + top$ + "-- " bst.file.website * + top$ + "-- See the " quote$ * "IEEEtran_bst_HOWTO.pdf" * quote$ * " manual for usage information." * + top$ + "** Natbib version - not for normal IEEE work." + top$ + } + { skip$ } + if$ +} + +FUNCTION {completed.message} +{ is.print.banners.to.terminal + { "" + top$ + "Done." + top$ + } + { skip$ } + if$ +} + + + + +%%%%%%%%%%%%%%%%%%%%%% +%% STRING CONSTANTS %% +%%%%%%%%%%%%%%%%%%%%%% + +FUNCTION {bbl.and}{ "and" } +FUNCTION {bbl.etal}{ "et~al." } +FUNCTION {bbl.editors}{ "eds." } +FUNCTION {bbl.editor}{ "ed." } +FUNCTION {bbl.edition}{ "ed." } +FUNCTION {bbl.volume}{ "vol." } +FUNCTION {bbl.of}{ "of" } +FUNCTION {bbl.number}{ "no." } +FUNCTION {bbl.in}{ "in" } +FUNCTION {bbl.pages}{ "pp." } +FUNCTION {bbl.page}{ "p." } +FUNCTION {bbl.chapter}{ "ch." } +FUNCTION {bbl.paper}{ "paper" } +FUNCTION {bbl.part}{ "pt." } +FUNCTION {bbl.patent}{ "Patent" } +FUNCTION {bbl.patentUS}{ "U.S." } +FUNCTION {bbl.revision}{ "Rev." } +FUNCTION {bbl.series}{ "ser." } +FUNCTION {bbl.standard}{ "Std." } +FUNCTION {bbl.techrep}{ "Tech. Rep." } +FUNCTION {bbl.the}{ "The" } +FUNCTION {bbl.mthesis}{ "Master's thesis" } +FUNCTION {bbl.phdthesis}{ "Ph.D. dissertation" } +FUNCTION {bbl.st}{ "st" } +FUNCTION {bbl.nd}{ "nd" } +FUNCTION {bbl.rd}{ "rd" } +FUNCTION {bbl.th}{ "th" } + + +% This is the LaTeX spacer that is used when a larger than normal space +% is called for (such as just before the address:publisher). +FUNCTION {large.space} { "\hskip 1em plus 0.5em minus 0.4em\relax " } + +% The LaTeX code for dashes that are used to represent repeated names. +% Note: Some older IEEE journals used something like +% "\rule{0.275in}{0.5pt}\," which is fairly thick and runs right along +% the baseline. However, the IEEE now uses a thinner, above baseline, +% six dash long sequence. +FUNCTION {repeated.name.dashes} { "------" } + + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% PREDEFINED STRING MACROS %% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +MACRO {jan} {"Jan."} +MACRO {feb} {"Feb."} +MACRO {mar} {"Mar."} +MACRO {apr} {"Apr."} +MACRO {may} {"May"} +MACRO {jun} {"Jun."} +MACRO {jul} {"Jul."} +MACRO {aug} {"Aug."} +MACRO {sep} {"Sep."} +MACRO {oct} {"Oct."} +MACRO {nov} {"Nov."} +MACRO {dec} {"Dec."} + + + +%%%%%%%%%%%%%%%%%% +%% ENTRY FIELDS %% +%%%%%%%%%%%%%%%%%% + +ENTRY + { address + assignee + author + booktitle + chapter + day + dayfiled + edition + editor + howpublished + institution + intype + journal + key + language + month + monthfiled + nationality + note + number + organization + pages + paper + publisher + school + series + revision + title + type + url + volume + year + yearfiled + CTLuse_article_number + CTLuse_paper + CTLuse_url + CTLuse_forced_etal + CTLmax_names_forced_etal + CTLnames_show_etal + CTLuse_alt_spacing + CTLalt_stretch_factor + CTLdash_repeated_names + CTLname_format_string + CTLname_latex_cmd + CTLname_url_prefix + } + {} + { label extra.label sort.label short.list} + + + + +%%%%%%%%%%%%%%%%%%%%%%% +%% INTEGER VARIABLES %% +%%%%%%%%%%%%%%%%%%%%%%% + +INTEGERS { prev.status.punct this.status.punct punct.std + punct.no punct.comma punct.period + prev.status.space this.status.space space.std + space.no space.normal space.large + prev.status.quote this.status.quote quote.std + quote.no quote.close + prev.status.nline this.status.nline nline.std + nline.no nline.newblock + status.cap cap.std + cap.no cap.yes} + +INTEGERS { longest.label.width multiresult nameptr namesleft number.label numnames } + +INTEGERS { is.use.number.for.article + is.use.paper + is.use.url + is.forced.et.al + max.num.names.before.forced.et.al + num.names.shown.with.forced.et.al + is.use.alt.interword.spacing + is.dash.repeated.names} + + +%%%%%%%%%%%%%%%%%%%%%% +%% STRING VARIABLES %% +%%%%%%%%%%%%%%%%%%%%%% + +STRINGS { bibinfo + longest.label + oldname + s + t + ALTinterwordstretchfactor + name.format.string + name.latex.cmd + name.url.prefix} + + + + +%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOW LEVEL FUNCTIONS %% +%%%%%%%%%%%%%%%%%%%%%%%%% + +FUNCTION {initialize.controls} +{ default.is.use.number.for.article 'is.use.number.for.article := + default.is.use.paper 'is.use.paper := + default.is.use.url 'is.use.url := + default.is.forced.et.al 'is.forced.et.al := + default.max.num.names.before.forced.et.al 'max.num.names.before.forced.et.al := + default.num.names.shown.with.forced.et.al 'num.names.shown.with.forced.et.al := + default.is.use.alt.interword.spacing 'is.use.alt.interword.spacing := + default.is.dash.repeated.names 'is.dash.repeated.names := + default.ALTinterwordstretchfactor 'ALTinterwordstretchfactor := + default.name.format.string 'name.format.string := + default.name.latex.cmd 'name.latex.cmd := + default.name.url.prefix 'name.url.prefix := +} + + +% This IEEEtran.bst features a very powerful and flexible mechanism for +% controlling the capitalization, punctuation, spacing, quotation, and +% newlines of the formatted entry fields. (Note: IEEEtran.bst does not need +% or use the newline/newblock feature, but it has been implemented for +% possible future use.) The output states of IEEEtran.bst consist of +% multiple independent attributes and, as such, can be thought of as being +% vectors, rather than the simple scalar values ("before.all", +% "mid.sentence", etc.) used in most other .bst files. +% +% The more flexible and complex design used here was motivated in part by +% the IEEE's rather unusual bibliography style. For example, the IEEE ends the +% previous field item with a period and large space prior to the publisher +% address; the @electronic entry types use periods as inter-item punctuation +% rather than the commas used by the other entry types; and URLs are never +% followed by periods even though they are the last item in the entry. +% Although it is possible to accommodate these features with the conventional +% output state system, the seemingly endless exceptions make for convoluted, +% unreliable and difficult to maintain code. +% +% IEEEtran.bst's output state system can be easily understood via a simple +% illustration of two most recently formatted entry fields (on the stack): +% +% CURRENT_ITEM +% "PREVIOUS_ITEM +% +% which, in this example, is to eventually appear in the bibliography as: +% +% "PREVIOUS_ITEM," CURRENT_ITEM +% +% It is the job of the output routine to take the previous item off of the +% stack (while leaving the current item at the top of the stack), apply its +% trailing punctuation (including closing quote marks) and spacing, and then +% to write the result to BibTeX's output buffer: +% +% "PREVIOUS_ITEM," +% +% Punctuation (and spacing) between items is often determined by both of the +% items rather than just the first one. The presence of quotation marks +% further complicates the situation because, in standard English, trailing +% punctuation marks are supposed to be contained within the quotes. +% +% IEEEtran.bst maintains two output state (aka "status") vectors which +% correspond to the previous and current (aka "this") items. Each vector +% consists of several independent attributes which track punctuation, +% spacing, quotation, and newlines. Capitalization status is handled by a +% separate scalar because the format routines, not the output routine, +% handle capitalization and, therefore, there is no need to maintain the +% capitalization attribute for both the "previous" and "this" items. +% +% When a format routine adds a new item, it copies the current output status +% vector to the previous output status vector and (usually) resets the +% current (this) output status vector to a "standard status" vector. Using a +% "standard status" vector in this way allows us to redefine what we mean by +% "standard status" at the start of each entry handler and reuse the same +% format routines under the various inter-item separation schemes. For +% example, the standard status vector for the @book entry type may use +% commas for item separators, while the @electronic type may use periods, +% yet both entry handlers exploit many of the exact same format routines. +% +% Because format routines have write access to the output status vector of +% the previous item, they can override the punctuation choices of the +% previous format routine! Therefore, it becomes trivial to implement rules +% such as "Always use a period and a large space before the publisher." By +% pushing the generation of the closing quote mark to the output routine, we +% avoid all the problems caused by having to close a quote before having all +% the information required to determine what the punctuation should be. +% +% The IEEEtran.bst output state system can easily be expanded if needed. +% For instance, it is easy to add a "space.tie" attribute value if the +% bibliography rules mandate that two items have to be joined with an +% unbreakable space. + +FUNCTION {initialize.status.constants} +{ #0 'punct.no := + #1 'punct.comma := + #2 'punct.period := + #0 'space.no := + #1 'space.normal := + #2 'space.large := + #0 'quote.no := + #1 'quote.close := + #0 'cap.no := + #1 'cap.yes := + #0 'nline.no := + #1 'nline.newblock := +} + +FUNCTION {std.status.using.comma} +{ punct.comma 'punct.std := + space.normal 'space.std := + quote.no 'quote.std := + nline.no 'nline.std := + cap.no 'cap.std := +} + +FUNCTION {std.status.using.period} +{ punct.period 'punct.std := + space.normal 'space.std := + quote.no 'quote.std := + nline.no 'nline.std := + cap.yes 'cap.std := +} + +FUNCTION {initialize.prev.this.status} +{ punct.no 'prev.status.punct := + space.no 'prev.status.space := + quote.no 'prev.status.quote := + nline.no 'prev.status.nline := + punct.no 'this.status.punct := + space.no 'this.status.space := + quote.no 'this.status.quote := + nline.no 'this.status.nline := + cap.yes 'status.cap := +} + +FUNCTION {this.status.std} +{ punct.std 'this.status.punct := + space.std 'this.status.space := + quote.std 'this.status.quote := + nline.std 'this.status.nline := +} + +FUNCTION {cap.status.std}{ cap.std 'status.cap := } + +FUNCTION {this.to.prev.status} +{ this.status.punct 'prev.status.punct := + this.status.space 'prev.status.space := + this.status.quote 'prev.status.quote := + this.status.nline 'prev.status.nline := +} + + +FUNCTION {not} +{ { #0 } + { #1 } + if$ +} + +FUNCTION {and} +{ { skip$ } + { pop$ #0 } + if$ +} + +FUNCTION {or} +{ { pop$ #1 } + { skip$ } + if$ +} + + +% convert the strings "yes" or "no" to #1 or #0 respectively +FUNCTION {yes.no.to.int} +{ "l" change.case$ duplicate$ + "yes" = + { pop$ #1 } + { duplicate$ "no" = + { pop$ #0 } + { "unknown boolean " quote$ * swap$ * quote$ * + " in " * cite$ * warning$ + #0 + } + if$ + } + if$ +} + + +% pushes true if the single char string on the stack is in the +% range of "0" to "9" +FUNCTION {is.num} +{ chr.to.int$ + duplicate$ "0" chr.to.int$ < not + swap$ "9" chr.to.int$ > not and +} + +% multiplies the integer on the stack by a factor of 10 +FUNCTION {bump.int.mag} +{ #0 'multiresult := + { duplicate$ #0 > } + { #1 - + multiresult #10 + + 'multiresult := + } + while$ +pop$ +multiresult +} + +% converts a single character string on the stack to an integer +FUNCTION {char.to.integer} +{ duplicate$ + is.num + { chr.to.int$ "0" chr.to.int$ - } + {"noninteger character " quote$ * swap$ * quote$ * + " in integer field of " * cite$ * warning$ + #0 + } + if$ +} + +% converts a string on the stack to an integer +FUNCTION {string.to.integer} +{ duplicate$ text.length$ 'namesleft := + #1 'nameptr := + #0 'numnames := + { nameptr namesleft > not } + { duplicate$ nameptr #1 substring$ + char.to.integer numnames bump.int.mag + + 'numnames := + nameptr #1 + + 'nameptr := + } + while$ +pop$ +numnames +} + + + + +% The output routines write out the *next* to the top (previous) item on the +% stack, adding punctuation and such as needed. Since IEEEtran.bst maintains +% the output status for the top two items on the stack, these output +% routines have to consider the previous output status (which corresponds to +% the item that is being output). Full independent control of punctuation, +% closing quote marks, spacing, and newblock is provided. +% +% "output.nonnull" does not check for the presence of a previous empty +% item. +% +% "output" does check for the presence of a previous empty item and will +% remove an empty item rather than outputing it. +% +% "output.warn" is like "output", but will issue a warning if it detects +% an empty item. + +FUNCTION {output.nonnull} +{ swap$ + prev.status.punct punct.comma = + { "," * } + { skip$ } + if$ + prev.status.punct punct.period = + { add.period$ } + { skip$ } + if$ + prev.status.quote quote.close = + { "''" * } + { skip$ } + if$ + prev.status.space space.normal = + { " " * } + { skip$ } + if$ + prev.status.space space.large = + { large.space * } + { skip$ } + if$ + write$ + prev.status.nline nline.newblock = + { newline$ "\newblock " write$ } + { skip$ } + if$ +} + +FUNCTION {output} +{ duplicate$ empty$ + 'pop$ + 'output.nonnull + if$ +} + +FUNCTION {output.warn} +{ 't := + duplicate$ empty$ + { pop$ "empty " t * " in " * cite$ * warning$ } + 'output.nonnull + if$ +} + +% "fin.entry" is the output routine that handles the last item of the entry +% (which will be on the top of the stack when "fin.entry" is called). + +FUNCTION {fin.entry} +{ this.status.punct punct.no = + { skip$ } + { add.period$ } + if$ + this.status.quote quote.close = + { "''" * } + { skip$ } + if$ +write$ +newline$ +} + + +FUNCTION {is.last.char.not.punct} +{ duplicate$ + "}" * add.period$ + #-1 #1 substring$ "." = +} + +FUNCTION {is.multiple.pages} +{ 't := + #0 'multiresult := + { multiresult not + t empty$ not + and + } + { t #1 #1 substring$ + duplicate$ "-" = + swap$ duplicate$ "," = + swap$ "+" = + or or + { #1 'multiresult := } + { t #2 global.max$ substring$ 't := } + if$ + } + while$ + multiresult +} + +FUNCTION {capitalize}{ "u" change.case$ "t" change.case$ } + +FUNCTION {emphasize} +{ duplicate$ empty$ + { pop$ "" } + { "\emph{" swap$ * "}" * } + if$ +} + +FUNCTION {do.name.latex.cmd} +{ name.latex.cmd + empty$ + { skip$ } + { name.latex.cmd "{" * swap$ * "}" * } + if$ +} + +% IEEEtran.bst uses its own \BIBforeignlanguage command which directly +% invokes the TeX hyphenation patterns without the need of the Babel +% package. Babel does a lot more than switch hyphenation patterns and +% its loading can cause unintended effects in many class files (such as +% IEEEtran.cls). +FUNCTION {select.language} +{ duplicate$ empty$ 'pop$ + { language empty$ 'skip$ + { "\BIBforeignlanguage{" language * "}{" * swap$ * "}" * } + if$ + } + if$ +} + +FUNCTION {tie.or.space.prefix} +{ duplicate$ text.length$ #3 < + { "~" } + { " " } + if$ + swap$ +} + +FUNCTION {get.bbl.editor} +{ editor num.names$ #1 > 'bbl.editors 'bbl.editor if$ } + +FUNCTION {space.word}{ " " swap$ * " " * } + + +% Field Conditioners, Converters, Checkers and External Interfaces + +FUNCTION {empty.field.to.null.string} +{ duplicate$ empty$ + { pop$ "" } + { skip$ } + if$ +} + +FUNCTION {either.or.check} +{ empty$ + { pop$ } + { "can't use both " swap$ * " fields in " * cite$ * warning$ } + if$ +} + +FUNCTION {empty.entry.warn} +{ author empty$ title empty$ howpublished empty$ + month empty$ year empty$ note empty$ url empty$ + and and and and and and + { "all relevant fields are empty in " cite$ * warning$ } + 'skip$ + if$ +} + + +% The bibinfo system provides a way for the electronic parsing/acquisition +% of a bibliography's contents as is done by ReVTeX. For example, a field +% could be entered into the bibliography as: +% \bibinfo{volume}{2} +% Only the "2" would show up in the document, but the LaTeX \bibinfo command +% could do additional things with the information. IEEEtran.bst does provide +% a \bibinfo command via "\providecommand{\bibinfo}[2]{#2}". However, it is +% currently not used as the bogus bibinfo functions defined here output the +% entry values directly without the \bibinfo wrapper. The bibinfo functions +% themselves (and the calls to them) are retained for possible future use. +% +% bibinfo.check avoids acting on missing fields while bibinfo.warn will +% issue a warning message if a missing field is detected. Prior to calling +% the bibinfo functions, the user should push the field value and then its +% name string, in that order. + +FUNCTION {bibinfo.check} +{ swap$ duplicate$ missing$ + { pop$ pop$ "" } + { duplicate$ empty$ + { swap$ pop$ } + { swap$ pop$ } + if$ + } + if$ +} + +FUNCTION {bibinfo.warn} +{ swap$ duplicate$ missing$ + { swap$ "missing " swap$ * " in " * cite$ * warning$ pop$ "" } + { duplicate$ empty$ + { swap$ "empty " swap$ * " in " * cite$ * warning$ } + { swap$ pop$ } + if$ + } + if$ +} + + +% The IEEE separates large numbers with more than 4 digits into groups of +% three. The IEEE uses a small space to separate these number groups. +% Typical applications include patent and page numbers. + +% number of consecutive digits required to trigger the group separation. +FUNCTION {large.number.trigger}{ #5 } + +% For numbers longer than the trigger, this is the blocksize of the groups. +% The blocksize must be less than the trigger threshold, and 2 * blocksize +% must be greater than the trigger threshold (can't do more than one +% separation on the initial trigger). +FUNCTION {large.number.blocksize}{ #3 } + +% What is actually inserted between the number groups. +FUNCTION {large.number.separator}{ "\," } + +% So as to save on integer variables by reusing existing ones, numnames +% holds the current number of consecutive digits read and nameptr holds +% the number that will trigger an inserted space. +FUNCTION {large.number.separate} +{ 't := + "" + #0 'numnames := + large.number.trigger 'nameptr := + { t empty$ not } + { t #-1 #1 substring$ is.num + { numnames #1 + 'numnames := } + { #0 'numnames := + large.number.trigger 'nameptr := + } + if$ + t #-1 #1 substring$ swap$ * + t #-2 global.max$ substring$ 't := + numnames nameptr = + { duplicate$ #1 nameptr large.number.blocksize - substring$ swap$ + nameptr large.number.blocksize - #1 + global.max$ substring$ + large.number.separator swap$ * * + nameptr large.number.blocksize - 'numnames := + large.number.blocksize #1 + 'nameptr := + } + { skip$ } + if$ + } + while$ +} + +% Converts all single dashes "-" to double dashes "--". +FUNCTION {n.dashify} +{ large.number.separate + 't := + "" + { t empty$ not } + { t #1 #1 substring$ "-" = + { t #1 #2 substring$ "--" = not + { "--" * + t #2 global.max$ substring$ 't := + } + { { t #1 #1 substring$ "-" = } + { "-" * + t #2 global.max$ substring$ 't := + } + while$ + } + if$ + } + { t #1 #1 substring$ * + t #2 global.max$ substring$ 't := + } + if$ + } + while$ +} + + +% This function detects entries with names that are identical to that of +% the previous entry and replaces the repeated names with dashes (if the +% "is.dash.repeated.names" user control is nonzero). +FUNCTION {name.or.dash} +{ 's := + oldname empty$ + { s 'oldname := s } + { s oldname = + { is.dash.repeated.names + { repeated.name.dashes } + { s 'oldname := s } + if$ + } + { s 'oldname := s } + if$ + } + if$ +} + +% Converts the number string on the top of the stack to +% "numerical ordinal form" (e.g., "7" to "7th"). There is +% no artificial limit to the upper bound of the numbers as the +% two least significant digits determine the ordinal form. +FUNCTION {num.to.ordinal} +{ duplicate$ #-2 #1 substring$ "1" = + { bbl.th * } + { duplicate$ #-1 #1 substring$ "1" = + { bbl.st * } + { duplicate$ #-1 #1 substring$ "2" = + { bbl.nd * } + { duplicate$ #-1 #1 substring$ "3" = + { bbl.rd * } + { bbl.th * } + if$ + } + if$ + } + if$ + } + if$ +} + +% If the string on the top of the stack begins with a number, +% (e.g., 11th) then replace the string with the leading number +% it contains. Otherwise retain the string as-is. s holds the +% extracted number, t holds the part of the string that remains +% to be scanned. +FUNCTION {extract.num} +{ duplicate$ 't := + "" 's := + { t empty$ not } + { t #1 #1 substring$ + t #2 global.max$ substring$ 't := + duplicate$ is.num + { s swap$ * 's := } + { pop$ "" 't := } + if$ + } + while$ + s empty$ + 'skip$ + { pop$ s } + if$ +} + +% Converts the word number string on the top of the stack to +% Arabic string form. Will be successful up to "tenth". +FUNCTION {word.to.num} +{ duplicate$ "l" change.case$ 's := + s "first" = + { pop$ "1" } + { skip$ } + if$ + s "second" = + { pop$ "2" } + { skip$ } + if$ + s "third" = + { pop$ "3" } + { skip$ } + if$ + s "fourth" = + { pop$ "4" } + { skip$ } + if$ + s "fifth" = + { pop$ "5" } + { skip$ } + if$ + s "sixth" = + { pop$ "6" } + { skip$ } + if$ + s "seventh" = + { pop$ "7" } + { skip$ } + if$ + s "eighth" = + { pop$ "8" } + { skip$ } + if$ + s "ninth" = + { pop$ "9" } + { skip$ } + if$ + s "tenth" = + { pop$ "10" } + { skip$ } + if$ +} + + +% Converts the string on the top of the stack to numerical +% ordinal (e.g., "11th") form. +FUNCTION {convert.edition} +{ duplicate$ empty$ 'skip$ + { duplicate$ #1 #1 substring$ is.num + { extract.num + num.to.ordinal + } + { word.to.num + duplicate$ #1 #1 substring$ is.num + { num.to.ordinal } + { "edition ordinal word " quote$ * edition * quote$ * + " may be too high (or improper) for conversion" * " in " * cite$ * warning$ + } + if$ + } + if$ + } + if$ +} + + + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LATEX BIBLIOGRAPHY CODE %% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% from plainnat.bst +FUNCTION {format.full.names} +{'s := + #1 'nameptr := + s num.names$ 'numnames := + numnames 'namesleft := + { namesleft #0 > } + { s nameptr + "{vv~}{ll}" format.name$ 't := + nameptr #1 > + { + namesleft #1 > + { ", " * t * } + { + numnames #2 > + { "," * } + 'skip$ + if$ + t "others" = + { " " bbl.etal * * } + { " " bbl.and * " " * * t * } + if$ + } + if$ + } + 't + if$ + nameptr #1 + 'nameptr := + namesleft #1 - 'namesleft := + } + while$ +} + +FUNCTION {author.editor.full} +{ author empty$ + { editor empty$ + { "" } + { editor format.full.names } + if$ + } + { author format.full.names } + if$ +} + +FUNCTION {author.full} +{ author empty$ + { "" } + { author format.full.names } + if$ +} + +FUNCTION {editor.full} +{ editor empty$ + { "" } + { editor format.full.names } + if$ +} + +FUNCTION {make.full.names} +{ type$ "book" = + type$ "inbook" = + or + { author.editor.full } + { type$ "proceedings" = + type$ "periodical" = + or + { editor.full } + { author.full } + if$ + } + if$ +} +% END from plainnat.bst + +FUNCTION {start.entry} +{ newline$ + "\bibitem[" write$ + label write$ + ")" make.full.names duplicate$ short.list = + { pop$ } + { * } + if$ + "]{" * write$ + cite$ write$ + "}" write$ + newline$ + "" + initialize.prev.this.status +} + +% Here we write out all the LaTeX code that we will need. The most involved +% code sequences are those that control the alternate interword spacing and +% foreign language hyphenation patterns. The heavy use of \providecommand +% gives users a way to override the defaults. Special thanks to Javier Bezos, +% Johannes Braams, Robin Fairbairns, Heiko Oberdiek, Donald Arseneau and all +% the other gurus on comp.text.tex for their help and advice on the topic of +% \selectlanguage, Babel and BibTeX. +FUNCTION {begin.bib} +{ "% Generated by IEEEtranN.bst, version: " bst.file.version * " (" * bst.file.date * ")" * + write$ newline$ + preamble$ empty$ 'skip$ + { preamble$ write$ newline$ } + if$ + "\begin{thebibliography}{" number.label int.to.str$ * "}" * + write$ newline$ + "\providecommand{\natexlab}[1]{#1}" + write$ newline$ + "\providecommand{\url}[1]{#1}" + write$ newline$ + "\csname url@samestyle\endcsname" + write$ newline$ + "\providecommand{\newblock}{\relax}" + write$ newline$ + "\providecommand{\bibinfo}[2]{#2}" + write$ newline$ + "\providecommand{\BIBentrySTDinterwordspacing}{\spaceskip=0pt\relax}" + write$ newline$ + "\providecommand{\BIBentryALTinterwordstretchfactor}{" + ALTinterwordstretchfactor * "}" * + write$ newline$ + "\providecommand{\BIBentryALTinterwordspacing}{\spaceskip=\fontdimen2\font plus " + write$ newline$ + "\BIBentryALTinterwordstretchfactor\fontdimen3\font minus \fontdimen4\font\relax}" + write$ newline$ + "\providecommand{\BIBforeignlanguage}[2]{{%" + write$ newline$ + "\expandafter\ifx\csname l@#1\endcsname\relax" + write$ newline$ + "\typeout{** WARNING: IEEEtranN.bst: No hyphenation pattern has been}%" + write$ newline$ + "\typeout{** loaded for the language `#1'. Using the pattern for}%" + write$ newline$ + "\typeout{** the default language instead.}%" + write$ newline$ + "\else" + write$ newline$ + "\language=\csname l@#1\endcsname" + write$ newline$ + "\fi" + write$ newline$ + "#2}}" + write$ newline$ + "\providecommand{\BIBdecl}{\relax}" + write$ newline$ + "\BIBdecl" + write$ newline$ +} + +FUNCTION {end.bib} +{ newline$ "\end{thebibliography}" write$ newline$ } + +FUNCTION {if.url.alt.interword.spacing} +{ is.use.alt.interword.spacing + { is.use.url + { url empty$ 'skip$ {"\BIBentryALTinterwordspacing" write$ newline$} if$ } + { skip$ } + if$ + } + { skip$ } + if$ +} + +FUNCTION {if.url.std.interword.spacing} +{ is.use.alt.interword.spacing + { is.use.url + { url empty$ 'skip$ {"\BIBentrySTDinterwordspacing" write$ newline$} if$ } + { skip$ } + if$ + } + { skip$ } + if$ +} + + + + +%%%%%%%%%%%%%%%%%%%%% +%% FORMAT HANDLERS %% +%%%%%%%%%%%%%%%%%%%%% + +%% Lower Level Formats (used by higher level formats) + +FUNCTION {format.address.org.or.pub.date} +{ 't := + "" + year empty$ + { "empty year in " cite$ * warning$ } + { skip$ } + if$ + address empty$ t empty$ and + year empty$ and month empty$ and + { skip$ } + { this.to.prev.status + this.status.std + cap.status.std + address "address" bibinfo.check * + t empty$ + { skip$ } + { punct.period 'prev.status.punct := + space.large 'prev.status.space := + address empty$ + { skip$ } + { ": " * } + if$ + t * + } + if$ + year empty$ month empty$ and + { skip$ } + { t empty$ address empty$ and + { skip$ } + { ", " * } + if$ + month empty$ + { year empty$ + { skip$ } + { year "year" bibinfo.check * } + if$ + } + { month "month" bibinfo.check * + year empty$ + { skip$ } + { " " * year "year" bibinfo.check * } + if$ + } + if$ + } + if$ + } + if$ +} + + +FUNCTION {format.names} +{ 'bibinfo := + duplicate$ empty$ 'skip$ { + this.to.prev.status + this.status.std + 's := + "" 't := + #1 'nameptr := + s num.names$ 'numnames := + numnames 'namesleft := + { namesleft #0 > } + { s nameptr + name.format.string + format.name$ + bibinfo bibinfo.check + 't := + nameptr #1 > + { nameptr num.names.shown.with.forced.et.al #1 + = + numnames max.num.names.before.forced.et.al > + is.forced.et.al and and + { "others" 't := + #1 'namesleft := + } + { skip$ } + if$ + namesleft #1 > + { ", " * t do.name.latex.cmd * } + { s nameptr "{ll}" format.name$ duplicate$ "others" = + { 't := } + { pop$ } + if$ + t "others" = + { " " * bbl.etal emphasize * } + { numnames #2 > + { "," * } + { skip$ } + if$ + bbl.and + space.word * t do.name.latex.cmd * + } + if$ + } + if$ + } + { t do.name.latex.cmd } + if$ + nameptr #1 + 'nameptr := + namesleft #1 - 'namesleft := + } + while$ + cap.status.std + } if$ +} + + + + +%% Higher Level Formats + +%% addresses/locations + +FUNCTION {format.address} +{ address duplicate$ empty$ 'skip$ + { this.to.prev.status + this.status.std + cap.status.std + } + if$ +} + + + +%% author/editor names + +FUNCTION {format.authors}{ author "author" format.names } + +FUNCTION {format.editors} +{ editor "editor" format.names duplicate$ empty$ 'skip$ + { ", " * + get.bbl.editor + capitalize + * + } + if$ +} + + + +%% date + +FUNCTION {format.date} +{ + month "month" bibinfo.check duplicate$ empty$ + year "year" bibinfo.check duplicate$ empty$ + { swap$ 'skip$ + { this.to.prev.status + this.status.std + cap.status.std + "there's a month but no year in " cite$ * warning$ } + if$ + * + } + { this.to.prev.status + this.status.std + cap.status.std + swap$ 'skip$ + { + swap$ + " " * swap$ + } + if$ + * + } + if$ +} + +FUNCTION {format.date.electronic} +{ month "month" bibinfo.check duplicate$ empty$ + year "year" bibinfo.check duplicate$ empty$ + { swap$ + { pop$ } + { "there's a month but no year in " cite$ * warning$ + pop$ ")" * "(" swap$ * + this.to.prev.status + punct.no 'this.status.punct := + space.normal 'this.status.space := + quote.no 'this.status.quote := + cap.yes 'status.cap := + } + if$ + } + { swap$ + { swap$ pop$ ")" * "(" swap$ * } + { "(" swap$ * ", " * swap$ * ")" * } + if$ + this.to.prev.status + punct.no 'this.status.punct := + space.normal 'this.status.space := + quote.no 'this.status.quote := + cap.yes 'status.cap := + } + if$ +} + + + +%% edition/title + +% Note: The IEEE considers the edition to be closely associated with +% the title of a book. So, in IEEEtran.bst the edition is normally handled +% within the formatting of the title. The format.edition function is +% retained here for possible future use. +FUNCTION {format.edition} +{ edition duplicate$ empty$ 'skip$ + { this.to.prev.status + this.status.std + convert.edition + status.cap + { "t" } + { "l" } + if$ change.case$ + "edition" bibinfo.check + "~" * bbl.edition * + cap.status.std + } + if$ +} + +% This is used to format the booktitle of a conference proceedings. +% Here we use the "intype" field to provide the user a way to +% override the word "in" (e.g., with things like "presented at") +% Use of intype stops the emphasis of the booktitle to indicate that +% we no longer mean the written conference proceedings, but the +% conference itself. +FUNCTION {format.in.booktitle} +{ booktitle "booktitle" bibinfo.check duplicate$ empty$ 'skip$ + { this.to.prev.status + this.status.std + select.language + intype missing$ + { emphasize + bbl.in " " * + } + { intype " " * } + if$ + swap$ * + cap.status.std + } + if$ +} + +% This is used to format the booktitle of collection. +% Here the "intype" field is not supported, but "edition" is. +FUNCTION {format.in.booktitle.edition} +{ booktitle "booktitle" bibinfo.check duplicate$ empty$ 'skip$ + { this.to.prev.status + this.status.std + select.language + emphasize + edition empty$ 'skip$ + { ", " * + edition + convert.edition + "l" change.case$ + * "~" * bbl.edition * + } + if$ + bbl.in " " * swap$ * + cap.status.std + } + if$ +} + +FUNCTION {format.article.title} +{ title duplicate$ empty$ 'skip$ + { this.to.prev.status + this.status.std + "t" change.case$ + } + if$ + "title" bibinfo.check + duplicate$ empty$ 'skip$ + { quote.close 'this.status.quote := + is.last.char.not.punct + { punct.std 'this.status.punct := } + { punct.no 'this.status.punct := } + if$ + select.language + "``" swap$ * + cap.status.std + } + if$ +} + +FUNCTION {format.article.title.electronic} +{ title duplicate$ empty$ 'skip$ + { this.to.prev.status + this.status.std + cap.status.std + "t" change.case$ + } + if$ + "title" bibinfo.check + duplicate$ empty$ + { skip$ } + { select.language } + if$ +} + +FUNCTION {format.book.title.edition} +{ title "title" bibinfo.check + duplicate$ empty$ + { "empty title in " cite$ * warning$ } + { this.to.prev.status + this.status.std + select.language + emphasize + edition empty$ 'skip$ + { ", " * + edition + convert.edition + status.cap + { "t" } + { "l" } + if$ + change.case$ + * "~" * bbl.edition * + } + if$ + cap.status.std + } + if$ +} + +FUNCTION {format.book.title} +{ title "title" bibinfo.check + duplicate$ empty$ 'skip$ + { this.to.prev.status + this.status.std + cap.status.std + select.language + emphasize + } + if$ +} + + + +%% journal + +FUNCTION {format.journal} +{ journal duplicate$ empty$ 'skip$ + { this.to.prev.status + this.status.std + cap.status.std + select.language + emphasize + } + if$ +} + + + +%% how published + +FUNCTION {format.howpublished} +{ howpublished duplicate$ empty$ 'skip$ + { this.to.prev.status + this.status.std + cap.status.std + } + if$ +} + + + +%% institutions/organization/publishers/school + +FUNCTION {format.institution} +{ institution duplicate$ empty$ 'skip$ + { this.to.prev.status + this.status.std + cap.status.std + } + if$ +} + +FUNCTION {format.organization} +{ organization duplicate$ empty$ 'skip$ + { this.to.prev.status + this.status.std + cap.status.std + } + if$ +} + +FUNCTION {format.address.publisher.date} +{ publisher "publisher" bibinfo.warn format.address.org.or.pub.date } + +FUNCTION {format.address.publisher.date.nowarn} +{ publisher "publisher" bibinfo.check format.address.org.or.pub.date } + +FUNCTION {format.address.organization.date} +{ organization "organization" bibinfo.check format.address.org.or.pub.date } + +FUNCTION {format.school} +{ school duplicate$ empty$ 'skip$ + { this.to.prev.status + this.status.std + cap.status.std + } + if$ +} + + + +%% volume/number/series/chapter/pages + +FUNCTION {format.volume} +{ volume empty.field.to.null.string + duplicate$ empty$ 'skip$ + { this.to.prev.status + this.status.std + bbl.volume + status.cap + { capitalize } + { skip$ } + if$ + swap$ tie.or.space.prefix + "volume" bibinfo.check + * * + cap.status.std + } + if$ +} + +FUNCTION {format.number} +{ number empty.field.to.null.string + duplicate$ empty$ 'skip$ + { this.to.prev.status + this.status.std + status.cap + { bbl.number capitalize } + { bbl.number } + if$ + swap$ tie.or.space.prefix + "number" bibinfo.check + * * + cap.status.std + } + if$ +} + +FUNCTION {format.number.if.use.for.article} +{ is.use.number.for.article + { format.number } + { "" } + if$ +} + +% The IEEE does not seem to tie the series so closely with the volume +% and number as is done in other bibliography styles. Instead the +% series is treated somewhat like an extension of the title. +FUNCTION {format.series} +{ series empty$ + { "" } + { this.to.prev.status + this.status.std + bbl.series " " * + series "series" bibinfo.check * + cap.status.std + } + if$ +} + + +FUNCTION {format.chapter} +{ chapter empty$ + { "" } + { this.to.prev.status + this.status.std + type empty$ + { bbl.chapter } + { type "l" change.case$ + "type" bibinfo.check + } + if$ + chapter tie.or.space.prefix + "chapter" bibinfo.check + * * + cap.status.std + } + if$ +} + + +% The intended use of format.paper is for paper numbers of inproceedings. +% The paper type can be overridden via the type field. +% We allow the type to be displayed even if the paper number is absent +% for things like "postdeadline paper" +FUNCTION {format.paper} +{ is.use.paper + { paper empty$ + { type empty$ + { "" } + { this.to.prev.status + this.status.std + type "type" bibinfo.check + cap.status.std + } + if$ + } + { this.to.prev.status + this.status.std + type empty$ + { bbl.paper } + { type "type" bibinfo.check } + if$ + " " * paper + "paper" bibinfo.check + * + cap.status.std + } + if$ + } + { "" } + if$ +} + + +FUNCTION {format.pages} +{ pages duplicate$ empty$ 'skip$ + { this.to.prev.status + this.status.std + duplicate$ is.multiple.pages + { + bbl.pages swap$ + n.dashify + } + { + bbl.page swap$ + } + if$ + tie.or.space.prefix + "pages" bibinfo.check + * * + cap.status.std + } + if$ +} + + + +%% technical report number + +FUNCTION {format.tech.report.number} +{ number "number" bibinfo.check + this.to.prev.status + this.status.std + cap.status.std + type duplicate$ empty$ + { pop$ + bbl.techrep + } + { skip$ } + if$ + "type" bibinfo.check + swap$ duplicate$ empty$ + { pop$ } + { tie.or.space.prefix * * } + if$ +} + + + +%% note + +FUNCTION {format.note} +{ note empty$ + { "" } + { this.to.prev.status + this.status.std + punct.period 'this.status.punct := + note #1 #1 substring$ + duplicate$ "{" = + { skip$ } + { status.cap + { "u" } + { "l" } + if$ + change.case$ + } + if$ + note #2 global.max$ substring$ * "note" bibinfo.check + cap.yes 'status.cap := + } + if$ +} + + + +%% patent + +FUNCTION {format.patent.date} +{ this.to.prev.status + this.status.std + year empty$ + { monthfiled duplicate$ empty$ + { "monthfiled" bibinfo.check pop$ "" } + { "monthfiled" bibinfo.check } + if$ + dayfiled duplicate$ empty$ + { "dayfiled" bibinfo.check pop$ "" * } + { "dayfiled" bibinfo.check + monthfiled empty$ + { "dayfiled without a monthfiled in " cite$ * warning$ + * + } + { " " swap$ * * } + if$ + } + if$ + yearfiled empty$ + { "no year or yearfiled in " cite$ * warning$ } + { yearfiled "yearfiled" bibinfo.check + swap$ + duplicate$ empty$ + { pop$ } + { ", " * swap$ * } + if$ + } + if$ + } + { month duplicate$ empty$ + { "month" bibinfo.check pop$ "" } + { "month" bibinfo.check } + if$ + day duplicate$ empty$ + { "day" bibinfo.check pop$ "" * } + { "day" bibinfo.check + month empty$ + { "day without a month in " cite$ * warning$ + * + } + { " " swap$ * * } + if$ + } + if$ + year "year" bibinfo.check + swap$ + duplicate$ empty$ + { pop$ } + { ", " * swap$ * } + if$ + } + if$ + cap.status.std +} + +FUNCTION {format.patent.nationality.type.number} +{ this.to.prev.status + this.status.std + nationality duplicate$ empty$ + { "nationality" bibinfo.warn pop$ "" } + { "nationality" bibinfo.check + duplicate$ "l" change.case$ "united states" = + { pop$ bbl.patentUS } + { skip$ } + if$ + " " * + } + if$ + type empty$ + { bbl.patent "type" bibinfo.check } + { type "type" bibinfo.check } + if$ + * + number duplicate$ empty$ + { "number" bibinfo.warn pop$ } + { "number" bibinfo.check + large.number.separate + swap$ " " * swap$ * + } + if$ + cap.status.std +} + + + +%% standard + +FUNCTION {format.organization.institution.standard.type.number} +{ this.to.prev.status + this.status.std + organization duplicate$ empty$ + { pop$ + institution duplicate$ empty$ + { "institution" bibinfo.warn } + { "institution" bibinfo.warn " " * } + if$ + } + { "organization" bibinfo.warn " " * } + if$ + type empty$ + { bbl.standard "type" bibinfo.check } + { type "type" bibinfo.check } + if$ + * + number duplicate$ empty$ + { "number" bibinfo.check pop$ } + { "number" bibinfo.check + large.number.separate + swap$ " " * swap$ * + } + if$ + cap.status.std +} + +FUNCTION {format.revision} +{ revision empty$ + { "" } + { this.to.prev.status + this.status.std + bbl.revision + revision tie.or.space.prefix + "revision" bibinfo.check + * * + cap.status.std + } + if$ +} + + +%% thesis + +FUNCTION {format.master.thesis.type} +{ this.to.prev.status + this.status.std + type empty$ + { + bbl.mthesis + } + { + type "type" bibinfo.check + } + if$ +cap.status.std +} + +FUNCTION {format.phd.thesis.type} +{ this.to.prev.status + this.status.std + type empty$ + { + bbl.phdthesis + } + { + type "type" bibinfo.check + } + if$ +cap.status.std +} + + + +%% URL + +FUNCTION {format.url} +{ is.use.url + { url empty$ + { "" } + { this.to.prev.status + this.status.std + cap.yes 'status.cap := + name.url.prefix " " * + "\url{" * url * "}" * + punct.no 'this.status.punct := + punct.period 'prev.status.punct := + space.normal 'this.status.space := + space.normal 'prev.status.space := + quote.no 'this.status.quote := + } + if$ + } + { "" } + if$ +} + + + + +%%%%%%%%%%%%%%%%%%%% +%% ENTRY HANDLERS %% +%%%%%%%%%%%%%%%%%%%% + + +% Note: In many journals, the IEEE (or the authors) tend not to show the number +% for articles, so the display of the number is controlled here by the +% switch "is.use.number.for.article" +FUNCTION {article} +{ std.status.using.comma + start.entry + if.url.alt.interword.spacing + format.authors "author" output.warn + name.or.dash + format.article.title "title" output.warn + format.journal "journal" bibinfo.check "journal" output.warn + format.volume output + format.number.if.use.for.article output + format.pages output + format.date "year" output.warn + format.note output + format.url output + fin.entry + if.url.std.interword.spacing +} + +FUNCTION {book} +{ std.status.using.comma + start.entry + if.url.alt.interword.spacing + author empty$ + { format.editors "author and editor" output.warn } + { format.authors output.nonnull } + if$ + name.or.dash + format.book.title.edition output + format.series output + author empty$ + { skip$ } + { format.editors output } + if$ + format.address.publisher.date output + format.volume output + format.number output + format.note output + format.url output + fin.entry + if.url.std.interword.spacing +} + +FUNCTION {booklet} +{ std.status.using.comma + start.entry + if.url.alt.interword.spacing + format.authors output + name.or.dash + format.article.title "title" output.warn + format.howpublished "howpublished" bibinfo.check output + format.organization "organization" bibinfo.check output + format.address "address" bibinfo.check output + format.date output + format.note output + format.url output + fin.entry + if.url.std.interword.spacing +} + +FUNCTION {electronic} +{ std.status.using.period + start.entry + if.url.alt.interword.spacing + format.authors output + name.or.dash + format.date.electronic output + format.article.title.electronic output + format.howpublished "howpublished" bibinfo.check output + format.organization "organization" bibinfo.check output + format.address "address" bibinfo.check output + format.note output + format.url output + fin.entry + empty.entry.warn + if.url.std.interword.spacing +} + +FUNCTION {inbook} +{ std.status.using.comma + start.entry + if.url.alt.interword.spacing + author empty$ + { format.editors "author and editor" output.warn } + { format.authors output.nonnull } + if$ + name.or.dash + format.book.title.edition output + format.series output + format.address.publisher.date output + format.volume output + format.number output + format.chapter output + format.pages output + format.note output + format.url output + fin.entry + if.url.std.interword.spacing +} + +FUNCTION {incollection} +{ std.status.using.comma + start.entry + if.url.alt.interword.spacing + format.authors "author" output.warn + name.or.dash + format.article.title "title" output.warn + format.in.booktitle.edition "booktitle" output.warn + format.series output + format.editors output + format.address.publisher.date.nowarn output + format.volume output + format.number output + format.chapter output + format.pages output + format.note output + format.url output + fin.entry + if.url.std.interword.spacing +} + +FUNCTION {inproceedings} +{ std.status.using.comma + start.entry + if.url.alt.interword.spacing + format.authors "author" output.warn + name.or.dash + format.article.title "title" output.warn + format.in.booktitle "booktitle" output.warn + format.series output + format.editors output + format.volume output + format.number output + publisher empty$ + { format.address.organization.date output } + { format.organization "organization" bibinfo.check output + format.address.publisher.date output + } + if$ + format.paper output + format.pages output + format.note output + format.url output + fin.entry + if.url.std.interword.spacing +} + +FUNCTION {manual} +{ std.status.using.comma + start.entry + if.url.alt.interword.spacing + format.authors output + name.or.dash + format.book.title.edition "title" output.warn + format.howpublished "howpublished" bibinfo.check output + format.organization "organization" bibinfo.check output + format.address "address" bibinfo.check output + format.date output + format.note output + format.url output + fin.entry + if.url.std.interword.spacing +} + +FUNCTION {mastersthesis} +{ std.status.using.comma + start.entry + if.url.alt.interword.spacing + format.authors "author" output.warn + name.or.dash + format.article.title "title" output.warn + format.master.thesis.type output.nonnull + format.school "school" bibinfo.warn output + format.address "address" bibinfo.check output + format.date "year" output.warn + format.note output + format.url output + fin.entry + if.url.std.interword.spacing +} + +FUNCTION {misc} +{ std.status.using.comma + start.entry + if.url.alt.interword.spacing + format.authors output + name.or.dash + format.article.title output + format.howpublished "howpublished" bibinfo.check output + format.organization "organization" bibinfo.check output + format.address "address" bibinfo.check output + format.pages output + format.date output + format.note output + format.url output + fin.entry + empty.entry.warn + if.url.std.interword.spacing +} + +FUNCTION {patent} +{ std.status.using.comma + start.entry + if.url.alt.interword.spacing + format.authors output + name.or.dash + format.article.title output + format.patent.nationality.type.number output + format.patent.date output + format.note output + format.url output + fin.entry + empty.entry.warn + if.url.std.interword.spacing +} + +FUNCTION {periodical} +{ std.status.using.comma + start.entry + if.url.alt.interword.spacing + format.editors output + name.or.dash + format.book.title "title" output.warn + format.series output + format.volume output + format.number output + format.organization "organization" bibinfo.check output + format.date "year" output.warn + format.note output + format.url output + fin.entry + if.url.std.interword.spacing +} + +FUNCTION {phdthesis} +{ std.status.using.comma + start.entry + if.url.alt.interword.spacing + format.authors "author" output.warn + name.or.dash + format.article.title "title" output.warn + format.phd.thesis.type output.nonnull + format.school "school" bibinfo.warn output + format.address "address" bibinfo.check output + format.date "year" output.warn + format.note output + format.url output + fin.entry + if.url.std.interword.spacing +} + +FUNCTION {proceedings} +{ std.status.using.comma + start.entry + if.url.alt.interword.spacing + format.editors output + name.or.dash + format.book.title "title" output.warn + format.series output + format.volume output + format.number output + publisher empty$ + { format.address.organization.date output } + { format.organization "organization" bibinfo.check output + format.address.publisher.date output + } + if$ + format.note output + format.url output + fin.entry + if.url.std.interword.spacing +} + +FUNCTION {standard} +{ std.status.using.comma + start.entry + if.url.alt.interword.spacing + format.authors output + name.or.dash + format.book.title "title" output.warn + format.howpublished "howpublished" bibinfo.check output + format.organization.institution.standard.type.number output + format.revision output + format.date output + format.note output + format.url output + fin.entry + if.url.std.interword.spacing +} + +FUNCTION {techreport} +{ std.status.using.comma + start.entry + if.url.alt.interword.spacing + format.authors "author" output.warn + name.or.dash + format.article.title "title" output.warn + format.howpublished "howpublished" bibinfo.check output + format.institution "institution" bibinfo.warn output + format.address "address" bibinfo.check output + format.tech.report.number output.nonnull + format.date "year" output.warn + format.note output + format.url output + fin.entry + if.url.std.interword.spacing +} + +FUNCTION {unpublished} +{ std.status.using.comma + start.entry + if.url.alt.interword.spacing + format.authors "author" output.warn + name.or.dash + format.article.title "title" output.warn + format.date output + format.note "note" output.warn + format.url output + fin.entry + if.url.std.interword.spacing +} + + +% The special entry type which provides the user interface to the +% BST controls +FUNCTION {IEEEtranBSTCTL} +{ is.print.banners.to.terminal + { "** IEEEtran BST control entry " quote$ * cite$ * quote$ * " detected." * + top$ + } + { skip$ } + if$ + CTLuse_article_number + empty$ + { skip$ } + { CTLuse_article_number + yes.no.to.int + 'is.use.number.for.article := + } + if$ + CTLuse_paper + empty$ + { skip$ } + { CTLuse_paper + yes.no.to.int + 'is.use.paper := + } + if$ + CTLuse_url + empty$ + { skip$ } + { CTLuse_url + yes.no.to.int + 'is.use.url := + } + if$ + CTLuse_forced_etal + empty$ + { skip$ } + { CTLuse_forced_etal + yes.no.to.int + 'is.forced.et.al := + } + if$ + CTLmax_names_forced_etal + empty$ + { skip$ } + { CTLmax_names_forced_etal + string.to.integer + 'max.num.names.before.forced.et.al := + } + if$ + CTLnames_show_etal + empty$ + { skip$ } + { CTLnames_show_etal + string.to.integer + 'num.names.shown.with.forced.et.al := + } + if$ + CTLuse_alt_spacing + empty$ + { skip$ } + { CTLuse_alt_spacing + yes.no.to.int + 'is.use.alt.interword.spacing := + } + if$ + CTLalt_stretch_factor + empty$ + { skip$ } + { CTLalt_stretch_factor + 'ALTinterwordstretchfactor := + "\renewcommand{\BIBentryALTinterwordstretchfactor}{" + ALTinterwordstretchfactor * "}" * + write$ newline$ + } + if$ + CTLdash_repeated_names + empty$ + { skip$ } + { CTLdash_repeated_names + yes.no.to.int + 'is.dash.repeated.names := + } + if$ + CTLname_format_string + empty$ + { skip$ } + { CTLname_format_string + 'name.format.string := + } + if$ + CTLname_latex_cmd + empty$ + { skip$ } + { CTLname_latex_cmd + 'name.latex.cmd := + } + if$ + CTLname_url_prefix + missing$ + { skip$ } + { CTLname_url_prefix + 'name.url.prefix := + } + if$ + + + num.names.shown.with.forced.et.al max.num.names.before.forced.et.al > + { "CTLnames_show_etal cannot be greater than CTLmax_names_forced_etal in " cite$ * warning$ + max.num.names.before.forced.et.al 'num.names.shown.with.forced.et.al := + } + { skip$ } + if$ +} + + +%%%%%%%%%%%%%%%%%%% +%% ENTRY ALIASES %% +%%%%%%%%%%%%%%%%%%% +FUNCTION {conference}{inproceedings} +FUNCTION {online}{electronic} +FUNCTION {internet}{electronic} +FUNCTION {webpage}{electronic} +FUNCTION {www}{electronic} +FUNCTION {default.type}{misc} + + + +%%%%%%%%%%%%%%%%%% +%% MAIN PROGRAM %% +%%%%%%%%%%%%%%%%%% + +READ + +EXECUTE {initialize.controls} +EXECUTE {initialize.status.constants} +EXECUTE {banner.message} + + + +% BEGIN sort code based on unsrtnat.bst +FUNCTION {sortify} +{ purify$ + "l" change.case$ +} + +INTEGERS { len } + +FUNCTION {chop.word} +{ 's := + 'len := + s #1 len substring$ = + { s len #1 + global.max$ substring$ } + { s } + if$ +} + +STRINGS { last.label next.extra } + +INTEGERS { last.extra.num } + +FUNCTION {format.lab.names} +{ 's := + s #1 "{vv~}{ll}" format.name$ + s num.names$ duplicate$ + #2 > + { pop$ " " bbl.etal * * } + { #2 < + 'skip$ + { s #2 "{ff }{vv }{ll}{ jj}" format.name$ "others" = + { " " bbl.etal * * } + { " " bbl.and * " " * * s #2 "{vv~}{ll}" format.name$ * } + if$ + } + if$ + } + if$ +} + +FUNCTION {author.key.label} +{ author empty$ + { key empty$ + { cite$ #1 #3 substring$ } + { key } + if$ + } + { author format.lab.names } + if$ +} + +FUNCTION {author.editor.key.label} +{ author empty$ + { editor empty$ + { key empty$ + { cite$ #1 #3 substring$ } + { key } + if$ + } + { editor format.lab.names } + if$ + } + { author format.lab.names } + if$ +} + +FUNCTION {author.key.organization.label} +{ author empty$ + { key empty$ + { organization empty$ + { cite$ #1 #3 substring$ } + { bbl.the " " * #4 organization chop.word #3 text.prefix$ } + if$ + } + { key } + if$ + } + { author format.lab.names } + if$ +} + +FUNCTION {author.key.organization.institution.label} +{ author empty$ + { key empty$ + { organization empty$ + { institution empty$ + { cite$ #1 #3 substring$ } + { bbl.the " " * #4 institution chop.word #3 text.prefix$ } + if$ + } + { bbl.the " " * #4 organization chop.word #3 text.prefix$ } + if$ + } + { key } + if$ + } + { author format.lab.names } + if$ +} + +FUNCTION {editor.key.organization.label} +{ editor empty$ + { key empty$ + { organization empty$ + { cite$ #1 #3 substring$ } + { bbl.the " " * #4 organization chop.word #3 text.prefix$ } + if$ + } + { key } + if$ + } + { editor format.lab.names } + if$ +} + +FUNCTION {calc.label} +{ type$ "book" = + type$ "inbook" = + or + { author.editor.key.label } + { type$ "proceedings" = + type$ "periodical" = + or + { editor.key.organization.label } + { type$ "manual" = + type$ "electronic" = + type$ "misc" = + or or + { author.key.organization.label } + { type$ "standard" = + { author.key.organization.institution.label } + { author.key.label } + if$ + } + if$ + } + if$ + } + if$ + duplicate$ + 'short.list := + "(" + * + type$ "patent" = + { year empty$ + { yearfiled } + { year } + if$ + } + { year } + if$ + duplicate$ + empty$ + short.list key empty.field.to.null.string = or + { pop$ "" } + { skip$ } + if$ + * + 'label := +} + + +INTEGERS { seq.num } + +FUNCTION {init.seq} +{ #0 'seq.num :=} + + +FUNCTION {int.to.fix} +{ "000000000" swap$ int.to.str$ * + #-1 #10 substring$ +} + + +FUNCTION {presort} +{ type$ "ieeetranbstctl" = + { key empty$ + { "_" } + { key sortify } + if$ + " " + * + seq.num int.to.fix + } + { calc.label + label sortify + " " + * + seq.num #1 + 'seq.num := + seq.num int.to.fix + } + if$ + 'sort.label := + sort.label * + #1 entry.max$ substring$ + 'sort.key$ := +} + + +FUNCTION {initialize.longest.label} +{ "" 'longest.label := + #0 int.to.chr$ 'last.label := + "" 'next.extra := + #0 'longest.label.width := + #0 'last.extra.num := + #0 'number.label := +} + +FUNCTION {forward.pass} +{ type$ "ieeetranbstctl" = + { skip$ } + { last.label label = + { last.extra.num #1 + 'last.extra.num := + last.extra.num int.to.chr$ 'extra.label := + } + { "a" chr.to.int$ 'last.extra.num := + "" 'extra.label := + label 'last.label := + } + if$ + number.label #1 + 'number.label := + } + if$ +} + +FUNCTION {reverse.pass} +{ type$ "ieeetranbstctl" = + { skip$ } + { next.extra "b" = + { "a" 'extra.label := } + { skip$ } + if$ + extra.label 'next.extra := + extra.label + duplicate$ empty$ + { skip$ } + { "{\natexlab{" swap$ * "}}" * } + if$ + 'extra.label := + label extra.label * 'label := + } + if$ +} + +FUNCTION {bib.sort.order} +{ sort.label 'sort.key$ := +} +% END sort code based on unsrtnat.bst + + + +EXECUTE {init.seq} + +ITERATE {presort} + +SORT + +EXECUTE {initialize.longest.label} + +ITERATE {forward.pass} +REVERSE {reverse.pass} + +ITERATE {bib.sort.order} + +SORT + +EXECUTE {begin.bib} +ITERATE {call.type$} +EXECUTE {end.bib} + +EXECUTE{completed.message} + + +%% That's all folks, mds. diff --git a/OSU Coursework/CS 444 - Operating Systems II/Kernel Assignments/Project 1/commands.tex b/OSU Coursework/CS 444 - Operating Systems II/Kernel Assignments/Project 1/commands.tex new file mode 100644 index 0000000..dd36594 --- /dev/null +++ b/OSU Coursework/CS 444 - Operating Systems II/Kernel Assignments/Project 1/commands.tex @@ -0,0 +1,15 @@ +\section{Commands} +\begin{itemize} +\item mkdir /scratch/spring2018/4 +\item cd /scratch/spring20128/4 +\item git init +\item wget http://git.yoctoproject.org/cgit.cgi/linux-yocto/snapshot/linux-yocto-3.19.2.tar.bz2 +\item tar xvjf linux-yocto-3.19.2.tar.bz2 +\item cp /scratch/files/bzImage-qemux86.bin . +\item cp /scratch/files/core-image-lsb-sdk-qemux86.ext4 . +\item cp /scratch/files/config-3.19.2-yocto-standard .config +\item source /scratch/files/environment-setup-i586-poky-linux.csh +\item make -j4 +\item qemu-system-i386 -gdb tcp::5004 -nographic -kernel bzImage-qemux86.bin -drive file=core-image-lsb-sdk-qemux86.ext4,if=virtio -enable-kvm -net none -usb -localtime --no-reboot --append "root=/dev/vda rw console=ttyS0 debug". + +\end{itemize} \ No newline at end of file diff --git a/OSU Coursework/CS 444 - Operating Systems II/Kernel Assignments/Project 1/flags.tex b/OSU Coursework/CS 444 - Operating Systems II/Kernel Assignments/Project 1/flags.tex new file mode 100644 index 0000000..e383169 --- /dev/null +++ b/OSU Coursework/CS 444 - Operating Systems II/Kernel Assignments/Project 1/flags.tex @@ -0,0 +1,53 @@ +\section{QEMU Flags} + +\begin{itemize} + \item \texttt{-gdb tcp::????} + + Waits for a GDB connection on the specified device, namely a TCP + connection on port ????. + + \item \texttt{-S} + + Prevents the CPU from starting up when first launching the command. + + \item \texttt{-nographic} + + Disables graphical capabilities and turns qemu into a command line + application. + + \item \texttt{-kernel bzImage-qemux86.bin} + + Uses the ``\texttt{bzImage-qemux86.bin}'' binary as the kernel image to boot. + + \item \texttt{-drive file=core-image-lsb-sdk-qemux86.ext4,if=virtio} + + Uses ``\texttt{core-image-lsb-sdk-qemux86.ext4}'' as the file for the virtual + hard drive, and virtio as the I/O interface (virtio virtualizes I/O + operations like disk reads/writes). + + \item \texttt{-enable-kvm} + + Enables use of kernel-based virtual machine technology. + + \item \texttt{-net none} + + Indicates that no network devices should be configured. + + \item \texttt{-usb} + + Enables USB drivers. + + \item \texttt{-localtime} + + Uses the local time from the host machine to set the time in the guest, + instead of the default of UTC time. + + \item \texttt{--no-reboot} + + Shuts down the guest entirely on exit instead of rebooting. + + \item \texttt{--append "root=/dev/vda rw console=ttyS0 debug"} + + Uses \texttt{"root=/dev/vda rw console=ttyS0 debug"} as the initial command line, + running it on initial boot. +\end{itemize} \ No newline at end of file diff --git a/OSU Coursework/CS 444 - Operating Systems II/Kernel Assignments/Project 1/homework1.tex b/OSU Coursework/CS 444 - Operating Systems II/Kernel Assignments/Project 1/homework1.tex new file mode 100644 index 0000000..d558f25 --- /dev/null +++ b/OSU Coursework/CS 444 - Operating Systems II/Kernel Assignments/Project 1/homework1.tex @@ -0,0 +1,107 @@ +\documentclass[onecolumn, draftclsnofoot, 10pt, compsoc]{IEEEtran} +\usepackage{graphicx} +\graphicspath{{./figures/}} + +\usepackage{url} +\usepackage{setspace} +\usepackage{multicol} +\usepackage{pdflscape} +\usepackage{pdfpages} +\usepackage[british]{babel} +\usepackage{listings} +\usepackage{xcolor} +\usepackage{listings} +\usepackage{hyperref} +\usepackage{subfig} + +\usepackage{geometry} +\geometry{textheight=9.5in, textwidth=7in} + +% \overfullrule=2in + + +%Personal \newcommands + +\definecolor{backcolor}{rgb}{0.95,0.95,0.92} +\lstset{basicstyle=\ttfamily, + backgroundcolor=\color{backcolor}, + showstringspaces=false, + commentstyle=\color{red}, + keywordstyle=\color{blue}, + columns=fullflexible, + breaklines=true, + postbreak=\mbox{\textcolor{red}{$\hookrightarrow$}\space}, +} + +\newcommand{\NameSigPair}[1]{ + \par + \makebox[2.75in][r]{#1} + \hfill + \makebox[3.25in]{ + \makebox[2.25in]{\hrulefill} + \hfill + \makebox[.75in]{\hrulefill} + } + \par\vspace{-12pt} + \textit{ + \tiny\noindent + \makebox[2.75in]{} + \hfill + \makebox[3.25in]{ + \makebox[2.25in][r]{Signature} + \hfill + \makebox[.75in][r]{Date} + } + } +} +% 3. If the document is not to be signed, uncomment the command below +\renewcommand{\NameSigPair}[1]{#1} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\begin{document} +\begin{titlepage} + \pagenumbering{gobble} + \begin{singlespace} + \par\vspace{2in} + \centering + \scshape{ + \huge Operating Systems II Homework 1 \par + {\large\today}\par + \vspace{.5in} + \vfill + \vspace{5pt} + {\large Prepared by }\par + Group 4 \par + % 5. comment out the line below this one if you do not wish to name your team + \vspace{5pt} + {\Large + \NameSigPair{Corinna Brown}\par + \NameSigPair{Zachary Comito}\par + \NameSigPair{Corwin Perren}\par + } + \vspace{20pt} + \begin{abstract} + The document is our groups submission for homework one covering the commands our group ran to finish the assignment, descriptions of qemu flags, answers to explicit assignment questions, a version control log, and work log. + + + \end{abstract} + } + \end{singlespace} +\end{titlepage} +\newpage +\pagenumbering{arabic} +\tableofcontents +\clearpage + +\input{commands} +\input{flags} +\input{questions} +\input{versioncontrollog} +\input{worklog} + +\end{document} + + + + + diff --git a/OSU Coursework/CS 444 - Operating Systems II/Kernel Assignments/Project 1/latexmk.pl b/OSU Coursework/CS 444 - Operating Systems II/Kernel Assignments/Project 1/latexmk.pl new file mode 100644 index 0000000..0a84e0e --- /dev/null +++ b/OSU Coursework/CS 444 - Operating Systems II/Kernel Assignments/Project 1/latexmk.pl @@ -0,0 +1,8802 @@ +#!/usr/bin/env perl + +# ?? Still need to fix bcf error issue. +# Don't keep looping after error +# pvc: Only re-run on USER FILE CHANGE. +# See # ??????? BCF + + +#!!!!!!!!??? Check @pwd_log + + +# !!!!!!!!!! Don't forget to document $silence_logfile_warnings.!!! + +# N.B. !!!!!!!!!!! See 17 July 2012 comments !!!!!!!!!!!!!!!!!! + +# On a UNIX-like system, the above enables latexmk to run independently +# of the location of the perl executable. This line relies on the +# existence of the program /usr/bin/env +# If there is a problem for any reason, you can replace the first line of +# this file by: + +#!/usr/bin/perl -w + +# with the path of the perl executable adjusted for your system. + +use warnings; + +# Delete #??!! when working + +# See ?? <=============================== + +## ?? Issues with clean-up +## List of aux files deleted is those read, not those generated. +## Other files are generated by (pdf)latex; should they be deleted? +## (I have hooks for this). + + + +#======================================= + +#?? Force mode doesn't appear to do force (if error in latex file) +#??? Get banner back in. +#?? CORRECT DIAGNOSTICS ON CHANGED FILES IF THEY DIDN'T EXIST BEFORE +#?? Further corrections to deal with disappeared source files for custom dependencies. +# Message repeatedly appears about remake when source file of cusdep doesn't exist. +#?? logfile w/o fdb file: don't set changed file, perhaps for generated exts. +# Reconsider +#?? Do proper run-stuff for bibtex, makeindex, cus-deps. OK I think +# Parse and correctly find ist files + + +# ATTEMPT TO ALLOW FILENAMES WITH SPACES: +# (as of 1 Apr 2006, and then 14 Sep. 2007) + +# Problems: +# A. Quoting filenames will not always work. +# a. Under UNIX, quotes are legal in filenames, so when PERL +# directly runs a binary, a quoted filename will be treated as +# as a filename containing a quote character. But when it calls +# a shell, the quotes are handled by the shell as quotes. +# b. Under MSWin32, quotes are illegal filename characters, and tend +# to be handled correctly. +# c. But under cygwin, results are not so clear (there are many +# combinations: native v. cygwin perl, native v cygwin programs +# NT v. unix scripts, which shell is called. +# B. TeX doesn't always handle filenames with spaces gracefully. +# a. UNIX/LINUX: The version on gluon2 Mar 31, 2006 to Sep. 2007) +# doesn't handle them at all. (TeX treats space as separator.) +# b. At least some later versions actually do (Brad Miller e-mail, +# Sep. 2007). +# c. fptex [[e-TeXk, Version 3.141592-2.1 (Web2c 7.5.2)] does, on +# my MSWin at home. In \input the filename must be in quotes. +# d. Bibtex [BibTeX (Web2c 7.5.2) 0.99c on my MSWin system at home, +# Sep. 2007] does not allow names of bibfiles to have spaces. +# C. =====> Using the shell for command lines is not safe, since special +# characters can cause lots of mayhem. +# It will therefore be a good idea to sanitize filenames. +# +# I've sanitized all calls out: +# a. system and exec use a single argument, which forces +# use of shell, under all circumstances +# Thus I can safely use quotes on filenames: They will be handled by +# the shell under UNIX, and simply passed on to the program under MSWin32. +# b. I reorganized Run, Run_Detached to use single command line +# c. All calls to Run and Run_Detached have quoted filenames. +# d. So if a space-free filename with wildcards is given on latexmk's +# command line, and it globs to space-containing filename(s), that +# works (fptex on home computer, native NT tex) +# e. ====> But globbing fails: the glob function takes space as filename +# separator. ==================== + +#================= TO DO ================ +# +# 1. See ?? ESPECIALLY $MSWin_fudge_break +# 2. Check fudged conditions in looping and make_files +# 3. Should not completely abort after a run that ends in failure from latex +# Missing input files (including via custom dependency) should be checked for +# a change in status +# If sources for missing files from custom dependency +# are available, then do a rerun +# If sources of any kind become available rerun (esp. for pvc) +# rerun +# Must parse log_file after unsuccessful run of latex: it may give +# information about missing files. +# 4. Check file of bug reports and requests +# 5. Rationalize bibtex warnings and errors. Two almost identical routines. +# Should 1. Use single routine +# 2. Convert errors to failure only in calling routine +# 3. Save first warning/error. + +# ?? Use of generated_exts arrays and hashes needs rationalization + +# To do: +# Rationalize again handling of include files. +# Now I use kpsewhich to do searches, if file not found +# (How do I avoid getting slowed down too much?) +# Document the assumptions at each stage of processing algorithm. +# Option to restart previewer automatically, if it dies under -pvc +# Test for already running previewer gets wrong answer if another +# process has the viewed file in its command line + +$my_name = 'latexmk'; +$My_name = 'Latexmk'; +$version_num = '4.52c'; +$version_details = "$My_name, John Collins, 19 Jan. 2017"; + +use Config; +use File::Basename; +use File::Copy; +use File::Glob ':glob'; # Better glob. Does not use space as item separator. +use File::Path 2.08 qw( make_path ); +use FileHandle; +use File::Find; +use List::Util qw( max ); +use Cwd; # To be able to change cwd +use Cwd "chdir"; # Ensure $ENV{PWD} tracks cwd +use Digest::MD5; + +#use strict; + +# The following variables are assigned once and then used in symbolic +# references, so we need to avoid warnings 'name used only once': +use vars qw( $dvi_update_command $ps_update_command $pdf_update_command ); + +# Translation of signal names to numbers and vv: +%signo = (); +@signame = (); +if ( defined $Config{sig_name} ) { + $i = 0; + foreach $name (split('\s+', $Config{sig_name})) { + $signo{$name} = $i; + $signame[$i] = $name; + $i++; + } +} +else { + warn "Something wrong with the perl configuration: No signals?\n"; +} + +## Copyright John Collins 1998-2017 +## (username jcc8 at node psu.edu) +## (and thanks to David Coppit (username david at node coppit.org) +## for suggestions) +## Copyright Evan McLean +## (modifications up to version 2) +## Copyright 1992 by David J. Musliner and The University of Michigan. +## (original version) +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program; if not, write to the Free Software +## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +## +## +## +## NEW FEATURES, since v. 2.0: +## 1. Correct algorithm for deciding how many times to run latex: +## based on whether source file(s) change between runs +## 2. Continuous preview works, and can be of ps file or dvi file +## 3. pdf creation by pdflatex possible +## 4. Defaults for commands are OS dependent. +## 5. Parsing of log file instead of source file is used to +## obtain dependencies, by default. +## +## Modification log from 9 Dec 2011 onwards in detail +## +## 12 Jan 2012 STILL NEED TO DOCUMENT some items below +## +## 19 Jan 2017 John Collins Make -jobname work with -pdfxe and -pdflua +## (v. 4.53c) +## 17 Jan 2017 John Collins Fix bbl file detection bug. +## Bbl files were previously only identified +## from occurrence as input files in log +## file rather than from fls as well. +## 16 Jan 2017 John Collins Clean up +## Add extra item to @file_not_found for +## xelatex's characteristic message. +## 14 Jan 2017 John Collins Fix some diagnostics. +## Detect graphics candidates in log file from +## <...> constructs. +## Don't look in log file for input files in the +## (...) and <...> constructs unless forced to +## by lack of up-to-date fls file. +## 13 Jan 2017 John Collins Kpsewhich diagnostics: also if not +## silent, or when $kpsewhich_show set. +## Optimize calls to kpsewhich to find files +## given by lines put in log file by +## graphics package. +## Work around LuaTeX line-wrapping bug. (LuaTeX 0.95.0) +## 12 Jan 2017 John Collins Improve error reporting on failed run. +## 11 Jan 2017 John Collins With -diagnositcs, include invocation +## and results for kpsewhich. +## 4, 10 Jan 2017 John Collins Finish fix for read-after-write files +## 29-31 Dec 2016 John Collins V. 4.51 +## For biber and bibtex rules, included .blg +## file as extra generated file. +## Similarly for makeindex rule +## 3 Nov 2016 John Collins Start to fix problem reported by jfbu +## that with deleted aux file, latexmk +## does too few runs. +## Problems: +## 1. latexmk doesn't create initial +## dummy aux or fdb when only one +## fails to exist, but only when +## both fail to exist. +## 2. latexmk detects the aux file as +## only read after write, and +## hence not a true dependent. +## That is the initial attempt to +## read, giving a No file message, +## is not recorded in the fls +## file. +## First fix: missing aux file => make +## dummy. +## Need better: if source file in fdb +## doesn't exist initially, then it +## should be counted as initially +## read, so not read after write. +## 18 Oct 2016 John Collins xelatex support via xdv file for speed. +## lualatex +## 5 Sep 2016 John Collins Add routines: rdb_list_source, rdb_set_source +## 17 Aug 2016 John Collins Add XDG Base Directory compatibility +## for per-user rc file +## 1 May 2016 John Collins Correct creation of output and aux directories +## to correctly handle relative paths when -cd +## is used. +## 22 Apr 2016 John Collins Fix problem of -C not always working correctly +## when compilation was with -pdf and clear was default. +## (Correctly default set of rules in rdb_make_rule_list.) +## Ver. 4.45 +## +## 1998-2010, John Collins. Many improvements and fixes. +## See CHANGE-log.txt for full list, and CHANGES for summary +## +## Modified by Evan McLean (no longer available for support) +## Original script (RCS version 2.3) called "go" written by David J. Musliner +## +##----------------------------------------------------------------------- + + +## Explicit exit codes: +## 10 = bad command line arguments +## 11 = file specified on command line not found +## or other file not found +## 12 = failure in some part of making files +## 13 = error in initialization file +## 20 = probable bug +## or retcode from called program. + + +# Line length in log file that indicates wrapping. +# This number EXCLUDES line-end characters, and is one-based. +# It is the parameter max_print_line in the TeX program. (tex.web) +$log_wrap = 79; + +######################################################################### +## Default parsing and file-handling settings + +## Array of reg-exps for patterns in log-file for file-not-found +## Each item is the string in a regexp, without the enclosing slashes. +## First parenthesized part is the filename. +## Note the need to quote slashes and single right quotes to make them +## appear in the regexp. +## Add items by push, e.g., +## push @file_not_found, '^No data file found `([^\\\']*)\\\''; +## will give match to line starting "No data file found `filename'" +@file_not_found = ( + '^No file\\s*(.*)\\.$', + '^\\! LaTeX Error: File `([^\\\']*)\\\' not found\\.', + '.*?:\\d*: LaTeX Error: File `([^\\\']*)\\\' not found\\.', + '^LaTeX Warning: File `([^\\\']*)\\\' not found', + '^Package .* [fF]ile `([^\\\']*)\\\' not found', + 'Error: pdflatex \(file ([^\)]*)\): cannot find image file', + ': File (.*) not found:\s*$', + '! Unable to load picture or PDF file \\\'([^\\\']+)\\\'.', +); + +## Hash mapping file extension (w/o period, e.g., 'eps') to a single regexp, +# whose matching by a line in a file with that extension indicates that the +# line is to be ignored in the calculation of the hash number (md5 checksum) +# for the file. Typically used for ignoring datestamps in testing whether +# a file has changed. +# Add items e.g., by +# $hash_calc_ignore_pattern{'eps'} = '^%%CreationDate: '; +# This makes the hash calculation for an eps file ignore lines starting with +# '%%CreationDate: ' +# ?? Note that a file will be considered changed if +# (a) its size changes +# or (b) its hash changes +# So it is useful to ignore lines in the hash calculation only if they +# are of a fixed size (as with a date/time stamp). +%hash_calc_ignore_pattern =(); + + +# Specification of templates for extra rules. +# See subroutine rdb_make_rule_list for examples of rule templates. +# See subroutine rdb_set_rules for how they get used to construct rules. +# (Documentation obviously needs to be improved!) +%extra_rule_spec = (); + + +# Hooks for customized extra processing on aux files. The following +# variable is an array of references to function. Each function is +# invoked in turn when a line of an aux file is processed (if none +# of the built-in actions have been done). On entry to the function, +# the following variables are set: +# $_ = current line of aux file +# $rule = name of rule during the invocation of which, the aux file +# was supposed to have been generated. +@aux_hooks = (); + +######################################################################### +## Default document processing programs, and related settings, +## These are mostly the same on all systems. +## Most of these variables represents the external command needed to +## perform a certain action. Some represent switches. + +## Commands to invoke latex, pdflatex, etc +$latex = 'latex %O %S'; +$pdflatex = 'pdflatex %O %S'; +$lualatex = 'lualatex %O %S'; +# xelatex is used to give xdv file, not pdf file +$xelatex = 'xelatex -no-pdf %O %S'; + +## Default switches: +$latex_default_switches = ''; +$pdflatex_default_switches = ''; +$lualatex_default_switches = ''; +$xelatex_default_switches = ''; + +## Switch(es) to make them silent: +$latex_silent_switch = '-interaction=batchmode'; +$pdflatex_silent_switch = '-interaction=batchmode'; +$lualatex_silent_switch = '-interaction=batchmode'; +$xelatex_silent_switch = '-interaction=batchmode'; + +# %input_extensions maps primary_rule_name to pointer to hash of file extensions +# used for extensionless files specified in the source file by constructs +# like \input{file} \includegraphics{file} +# Could write +#%input_extensions = ( 'latex' => { 'tex' => 1, 'eps' => 1 };, +# 'pdflatex' => { 'tex' => 1, 'pdf' => 1, 'jpg' => 1, 'png' => 1 }; ); +# Instead we'll exercise the user-friendly access routines: +add_input_ext( 'latex', 'tex', 'eps' ); +add_input_ext( 'pdflatex', 'tex', 'jpg', 'pdf', 'png' ); +add_input_ext( 'lualatex', 'tex', 'jpg', 'pdf', 'png' ); +add_input_ext( 'xelatex', 'tex', 'jpg', 'pdf', 'png' ); +#show_input_ext( 'latex' ); show_input_ext( 'pdflatex' ); + +# Information about options to latex and pdflatex that latexmk will simply +# pass through to (pdf)latex +# Option without arg. maps to itself. +# Option with arg. maps the option part to the full specification +# e.g., -kpathsea-debug => -kpathsea-debug=NUMBER +%allowed_latex_options = (); +%allowed_latex_options_with_arg = (); +foreach ( + ##### + # TeXLive options + "-draftmode switch on draft mode (generates no output PDF)", + "-enc enable encTeX extensions such as \\mubyte", + "-etex enable e-TeX extensions", + "-file-line-error enable file:line:error style messages", + "-no-file-line-error disable file:line:error style messages", + "-fmt=FMTNAME use FMTNAME instead of program name or a %& line", + "-halt-on-error stop processing at the first error", + "-interaction=STRING set interaction mode (STRING=batchmode/nonstopmode/\n". + " scrollmode/errorstopmode)", + "-ipc send DVI output to a socket as well as the usual\n". + " output file", + "-ipc-start as -ipc, and also start the server at the other end", + "-kpathsea-debug=NUMBER set path searching debugging flags according to\n". + " the bits of NUMBER", + "-mktex=FMT enable mktexFMT generation (FMT=tex/tfm/pk)", + "-no-mktex=FMT disable mktexFMT generation (FMT=tex/tfm/pk)", + "-mltex enable MLTeX extensions such as \charsubdef", + "-output-comment=STRING use STRING for DVI file comment instead of date\n". + " (no effect for PDF)", + "-output-format=FORMAT use FORMAT for job output; FORMAT is `dvi\" or `pdf\"", + "-parse-first-line enable parsing of first line of input file", + "-no-parse-first-line disable parsing of first line of input file", + "-progname=STRING set program (and fmt) name to STRING", + "-shell-escape enable \\write18{SHELL COMMAND}", + "-no-shell-escape disable \\write18{SHELL COMMAND}", + "-shell-restricted enable restricted \\write18", + "-src-specials insert source specials into the DVI file", + "-src-specials=WHERE insert source specials in certain places of\n". + " the DVI file. WHERE is a comma-separated value\n". + " list: cr display hbox math par parend vbox", + "-synctex=NUMBER generate SyncTeX data for previewers if nonzero", + "-translate-file=TCXNAME use the TCX file TCXNAME", + "-8bit make all characters printable by default", + + ##### + # MikTeX options not in TeXLive + "-alias=app pretend to be app", + "-buf-size=n maximum number of characters simultaneously present\n". + " in current lines", + "-c-style-errors C-style error messages", + "-disable-installer disable automatic installation of missing packages", + "-disable-pipes disable input (output) from (to) child processes", + "-disable-write18 disable the \\write18{command} construct", + "-dont-parse-first-line disable checking whether the first line of the main\n". + " input file starts with %&", + "-enable-enctex enable encTeX extensions such as \\mubyte", + "-enable-installer enable automatic installation of missing packages", + "-enable-mltex enable MLTeX extensions such as \charsubdef", + "-enable-pipes enable input (output) from (to) child processes", + "-enable-write18 fully enable the \\write18{command} construct", + "-error-line=n set the width of context lines on terminal error\n". + " messages", + "-extra-mem-bot=n set the extra size (in memory words) for large data\n". + " structures", + "-extra-mem-top=n set the extra size (in memory words) for chars,\n". + " tokens, et al", + "-font-max=n set the maximum internal font number", + "-font-mem-size=n set the size, in TeX memory words, of the font memory", + "-half-error-line=n set the width of first lines of contexts in terminal\n". + " error messages", + "-hash-extra=n set the extra space for the hash table of control\n". + " sequences", + "-job-time=file set the time-stamp of all output files equal to\n". + " file's time-stamp", + "-main-memory=n change the total size (in memory words) of the main\n". + " memory array", + "-max-in-open=n set the maximum number of input files and error\n". + " insertions that can be going on simultaneously", + "-max-print-line=n set the width of longest text lines output", + "-max-strings=n set the maximum number of strings", + "-nest-size=n set the maximum number of semantic levels\n". + " simultaneously active", + "-no-c-style-errors standard error messages", + "-param-size=n set the the maximum number of simultaneous macro\n". + " parameters", + "-pool-size=n set the maximum number of characters in strings", + "-record-package-usages=file record all package usages and write them into\n". + " file", + "-restrict-write18 partially enable the \\write18{command} construct", + "-save-size=n set the the amount of space for saving values\n". + " outside of current group", + "-stack-size=n set the maximum number of simultaneous input sources", + "-string-vacancies=n set the minimum number of characters that should be\n". + " available for the user's control sequences and font\n". + " names", + "-tcx=name process the TCX table name", + "-time-statistics show processing time statistics", + "-trace enable trace messages", + "-trace=tracestreams enable trace messages. The tracestreams argument is\n". + " a comma-separated list of trace stream names", + "-trie-size=n set the amount of space for hyphenation patterns", + "-undump=name use name as the name of the format to be used,\n". + " instead of the name by which the program was\n". + " called or a %& line.", + + ##### + # Options passed to (pdf)latex that have special processing by latexmk, + # so they are commented out here. + #-jobname=STRING set the job name to STRING + #-aux-directory=dir Set the directory dir to which auxiliary files are written + #-output-directory=DIR use existing DIR as the directory to write files in + #-quiet + #-recorder enable filename recorder + # + # Options with different processing by latexmk than (pdf)latex + #-help + #-version + # + # Options NOT used by latexmk + #-includedirectory=dir prefix dir to the search path + #-initialize become the INI variant of the compiler + #-ini be pdfinitex, for dumping formats; this is implicitly + # true if the program name is `pdfinitex' +) { + if ( /^([^\s=]+)=/ ) { + $allowed_latex_options_with_arg{$1} = $_; + } + elsif ( /^([^\s=]+)\s/ ) { + $allowed_latex_options{$1} = $_; + } + else { + $allowed_latex_options{$_} = $_; + } +} + +# Arrays of options that will be added to latex and pdflatex. +# These need to be stored until after the command line parsing is finished, +# in case the values of $latex and/or $pdflatex change after an option +# is added. +@extra_latex_options = (); +@extra_pdflatex_options = (); +@extra_lualatex_options = (); +@extra_xelatex_options = (); + + +## Command to invoke biber & bibtex +$biber = 'biber %O %B'; +$bibtex = 'bibtex %O %B'; +# Switch(es) to make biber & bibtex silent: +$biber_silent_switch = '--onlylog'; +$bibtex_silent_switch = '-terse'; +$bibtex_use = 1; # Whether to actually run bibtex to update bbl files + # 0: Never run bibtex + # 1: Run bibtex only if the bibfiles exists + # according to kpsewhich, and the bbl files + # appear to be out-of-date + # 2: Run bibtex when the bbl files are out-of-date + # In any event bibtex is only run if the log file + # indicates that the document uses bbl files. + +## Command to invoke makeindex +$makeindex = 'makeindex %O -o %D %S'; +# Switch(es) to make makeinex silent: +$makeindex_silent_switch = '-q'; + +## Command to convert dvi file to pdf file directly: +$dvipdf = 'dvipdf %O %S %D'; +# N.B. Standard dvipdf runs dvips and gs with their silent switch, so for +# standard dvipdf $dvipdf_silent_switch is unneeded, but innocuous. +# But dvipdfmx can be used instead, and it has a silent switch (-q). +# So implementing $dvipdf_silent_switch is useful. + +$dvipdf_silent_switch = '-q'; + +## Command to convert dvi file to ps file: +$dvips = 'dvips %O -o %D %S'; +## Command to convert dvi file to ps file in landscape format: +$dvips_landscape = 'dvips -tlandscape %O -o %D %S'; +# Switch(es) to get dvips to make ps file suitable for conversion to good pdf: +# (If this is not used, ps file and hence pdf file contains bitmap fonts +# (type 3), which look horrible under acroread. An appropriate switch +# ensures type 1 fonts are generated. You can put this switch in the +# dvips command if you prefer.) +$dvips_pdf_switch = '-P pdf'; +# Switch(es) to make dvips silent: +$dvips_silent_switch = '-q'; + +## Command to convert ps file to pdf file: +$ps2pdf = 'ps2pdf %O %S %D'; + +## Command to convert xdv file to pdf file +$xdvipdfmx = 'xdvipdfmx -o %D %O %S'; +$xdvipdfmx_silent_switch = '-q'; + + +## Command to search for tex-related files +$kpsewhich = 'kpsewhich %S'; + +## Command to run make: +$make = 'make'; + +##Printing: +$print_type = 'auto'; # When printing, print the postscript file. + # Possible values: 'dvi', 'ps', 'pdf', 'auto', 'none' + # 'auto' ==> set print type according to the printable + # file(s) being made: priority 'ps', 'pdf', 'dvi' + +## Which treatment of default extensions and filenames with +## multiple extensions is used, for given filename on +## tex/latex's command line? See sub find_basename for the +## possibilities. +## Current tex's treat extensions like UNIX teTeX: +$extension_treatment = 'unix'; + +## Substitute backslashes in file and directory names for +## MSWin command line +$MSWin_back_slash = 1; + +$dvi_update_signal = undef; +$ps_update_signal = undef; +$pdf_update_signal = undef; + +$dvi_update_command = undef; +$ps_update_command = undef; +$pdf_update_command = undef; + +$allow_subdir_creation = 1; + +$new_viewer_always = 0; # If 1, always open a new viewer in pvc mode. + # If 0, only open a new viewer if no previous + # viewer for the same file is detected. + +$quote_filenames = 1; # Quote filenames in external commands + +$del_dir = ''; # Directory into which cleaned up files are to be put. + # If $del_dir is '', just delete the files + +@rc_system_files = (); + +######################################################################### + +################################################################ +## Special variables for system-dependent fudges, etc. +$log_file_binary = 0; # Whether to treat log file as binary + # Normally not, since the log file SHOULD be pure text. + # But Miktex 2.7 sometimes puts binary characters + # in it. (Typically in construct \OML ... after + # overfull box with mathmode.) + # Sometimes there is ctrl/Z, which is not only non-text, + # but is end-of-file marker for MS-Win in text mode. + +$MSWin_fudge_break = 1; # Give special treatment to ctrl/C and ctrl/break + # in -pvc mode under MSWin + # Under MSWin32 (at least with perl 5.8 and WinXP) + # when latexmk is running another program, and the + # user gives ctrl/C or ctrl/break, to stop the + # daughter program, not only does it reach + # the daughter, but also latexmk/perl, so + # latexmk is stopped also. In -pvc mode, + # this is not normally desired. So when the + # $MSWin_fudge_break variable is set, + # latexmk arranges to ignore ctrl/C and + # ctrl/break during processing of files; + # only the daughter programs receive them. + # This fudge is not applied in other + # situations, since then having latexmk also + # stopping because of the ctrl/C or + # ctrl/break signal is desirable. + # The fudge is not needed under UNIX (at least + # with Perl 5.005 on Solaris 8). Only the + # daughter programs receive the signal. In + # fact the inverse would be useful: In + # normal processing, as opposed to -pvc, if + # force mode (-f) is set, a ctrl/C is + # received by a daughter program does not + # also stop latexmk. Under tcsh, we get + # back to a command prompt, while latexmk + # keeps running in the background! + + +################################################################ + + +# System-dependent overrides: +# Currently, the cases I have tests for are: MSWin32, cygwin, linux and +# darwin, with the main complications being for MSWin32 and cygwin. +# Special treatment may also be useful for MSYS (for which $^O reports +# "msys"). This is another *nix-emulation/system for MSWindows. At +# present it is treated as unix-like, but the environment variables +# are those of Windows. (The test for USERNAME as well as USER was +# to make latexmk work under MSYS's perl.) +# +if ( $^O eq "MSWin32" ) { +# Pure MSWindows configuration + ## Configuration parameters: + + ## Use first existing case for $tmpdir: + $tmpdir = $ENV{TMPDIR} || $ENV{TEMP} || '.'; + $log_file_binary = 1; # Protect against ctrl/Z in log file from + # Miktex 2.7. + + ## List of possibilities for the system-wide initialization file. + ## The first one found (if any) is used. + @rc_system_files = ( "C:/latexmk/LatexMk", "C:/latexmk/latexmkrc" ); + + $search_path_separator = ';'; # Separator of elements in search_path + + # For a pdf-file, "start x.pdf" starts the pdf viewer associated with + # pdf files, so no program name is needed: + $pdf_previewer = 'start %O %S'; + $ps_previewer = 'start %O %S'; + $ps_previewer_landscape = $ps_previewer; + $dvi_previewer = 'start %O %S'; + $dvi_previewer_landscape = "$dvi_previewer"; + # Viewer update methods: + # 0 => auto update: viewer watches file (e.g., gv) + # 1 => manual update: user must do something: e.g., click on window. + # (e.g., ghostview, MSWIN previewers, acroread under UNIX) + # 2 => send signal. Number of signal in $dvi_update_signal, + # $ps_update_signal, $pdf_update_signal + # 3 => viewer can't update, because it locks the file and the file + # cannot be updated. (acroread under MSWIN) + # 4 => run a command to force the update. The commands are + # specified by the variables $dvi_update_command, + # $ps_update_command, $pdf_update_command + $dvi_update_method = 1; + $ps_update_method = 1; + $pdf_update_method = 3; # acroread locks the pdf file + # Use NONE as flag that I am not implementing some commands: + $lpr = + 'NONE $lpr variable is not configured to allow printing of ps files'; + $lpr_dvi = + 'NONE $lpr_dvi variable is not configured to allow printing of dvi files'; + $lpr_pdf = + 'NONE $lpr_pdf variable is not configured to allow printing of pdf files'; + # The $pscmd below holds a command to list running processes. It + # is used to find the process ID of the viewer looking at the + # current output file. The output of the command must include the + # process number and the command line of the processes, since the + # relevant process is identified by the name of file to be viewed. + # Its use is not essential. + $pscmd = + 'NONE $pscmd variable is not configured to detect running processes'; + $pid_position = -1; # offset of PID in output of pscmd. + # Negative means I cannot use ps +} +elsif ( $^O eq "cygwin" ) { + # The problem is a mixed MSWin32 and UNIX environment. + # Perl decides the OS is cygwin in two situations: + # 1. When latexmk is run from a cygwin shell under a cygwin + # environment. Perl behaves in a UNIX way. This is OK, since + # the user is presumably expecting UNIXy behavior. + # 2. When CYGWIN exectuables are in the path, but latexmk is run + # from a native NT shell. Presumably the user is expecting NT + # behavior. But perl behaves more UNIXy. This causes some + # clashes. + # The issues to handle are: + # 1. Perl sees both MSWin32 and cygwin filenames. This is + # normally only an advantage. + # 2. Perl uses a UNIX shell in the system command + # This is a nasty problem: under native NT, there is a + # start command that knows about NT file associations, so that + # we can do, e.g., (under native NT) system("start file.pdf"); + # But this won't work when perl has decided the OS is cygwin, + # even if it is invoked from a native NT command line. An + # NT command processor must be used to deal with this. + # 3. External executables can be native NT (which only know + # NT-style file names) or cygwin executables (which normally + # know both cygwin UNIX-style file names and NT file names, + # but not always; some do not know about drive names, for + # example). + # Cygwin executables for tex and latex may only know cygwin + # filenames. + # 4. The BIBINPUTS environment variables may be + # UNIX-style or MSWin-style depending on whether native NT or + # cygwin executables are used. They are therefore parsed + # differently. Here is the clash: + # a. If a user is running under an NT shell, is using a + # native NT installation of tex (e.g., fptex or miktex), + # but has the cygwin executables in the path, then perl + # detects the OS as cygwin, but the user needs NT + # behavior from latexmk. + # b. If a user is running under an UNIX shell in a cygwin + # environment, and is using the cygwin installation of + # tex, then perl detects the OS as cygwin, and the user + # needs UNIX behavior from latexmk. + # Latexmk has no way of detecting the difference. The two + # situations may even arise for the same user on the same + # computer simply by changing the order of directories in the + # path environment variable + + + ## Configuration parameters: We'll assume native NT executables. + ## The user should override if they are not. + + # This may fail: perl converts MSWin temp directory name to cygwin + # format. Names containing this string cannot be handled by native + # NT executables. + $tmpdir = $ENV{TMPDIR} || $ENV{TEMP} || '.'; + + ## List of possibilities for the system-wide initialization file. + ## The first one found (if any) is used. + ## We could stay with MSWin files here, since cygwin perl understands them + ## @rc_system_files = ( 'C:/latexmk/LatexMk', 'C:/latexmk/latexmkrc' ); + ## But they are deprecated in v. 1.7. So use the UNIX version, prefixed + ## with a cygwin equivalent of the MSWin location + ## In addition, we need to add the same set of possible locations as with + ## unix, so that the user use a unix-style setup. + @rc_system_files = (); + foreach ( 'LatexMk', 'latexmkrc' ) { + push @rc_system_files, + ( "/cygdrive/c/latexmk/$_", + "/opt/local/share/latexmk/$_", + "/usr/local/share/latexmk/$_", + "/usr/local/lib/latexmk/$_" ); + } + $search_path_separator = ';'; # Separator of elements in search_path + # This is tricky. The search_path_separator depends on the kind + # of executable: native NT v. cygwin. + # So the user will have to override this. + + # We will assume that files can be viewed by native NT programs. + # Then we must fix the start command/directive, so that the + # NT-native start command of a cmd.exe is used. + # For a pdf-file, "start x.pdf" starts the pdf viewer associated with + # pdf files, so no program name is needed: + $start_NT = "cmd /c start \"\""; + $pdf_previewer = "$start_NT %O %S"; + $ps_previewer = "$start_NT %O %S"; + $ps_previewer_landscape = $ps_previewer; + $dvi_previewer = "$start_NT %O %S"; + $dvi_previewer_landscape = $dvi_previewer; + # Viewer update methods: + # 0 => auto update: viewer watches file (e.g., gv) + # 1 => manual update: user must do something: e.g., click on window. + # (e.g., ghostview, MSWIN previewers, acroread under UNIX) + # 2 => send signal. Number of signal in $dvi_update_signal, + # $ps_update_signal, $pdf_update_signal + # 3 => viewer can't update, because it locks the file and the file + # cannot be updated. (acroread under MSWIN) + $dvi_update_method = 1; + $ps_update_method = 1; + $pdf_update_method = 3; # acroread locks the pdf file + # Use NONE as flag that I am not implementing some commands: + $lpr = + 'NONE $lpr variable is not configured to allow printing of ps files'; + $lpr_dvi = + 'NONE $lpr_dvi variable is not configured to allow printing of dvi files'; + $lpr_pdf = + 'NONE $lpr_pdf variable is not configured to allow printing of pdf files'; + # The $pscmd below holds a command to list running processes. It + # is used to find the process ID of the viewer looking at the + # current output file. The output of the command must include the + # process number and the command line of the processes, since the + # relevant process is identified by the name of file to be viewed. + # Its use is not essential. + # When the OS is detected as cygwin, there are two possibilities: + # a. Latexmk was run from an NT prompt, but cygwin is in the + # path. Then the cygwin ps command will not see commands + # started from latexmk. So we cannot use it. + # b. Latexmk was started within a cygwin environment. Then + # the ps command works as we need. + # Only the user, not latemk knows which, so we default to not + # using the ps command. The user can override this in a + # configuration file. + $pscmd = + 'NONE $pscmd variable is not configured to detect running processes'; + $pid_position = -1; # offset of PID in output of pscmd. + # Negative means I cannot use ps +} +else { + # Assume anything else is UNIX or clone + + ## Configuration parameters: + + + ## Use first existing case for $tmpdir: + $tmpdir = $ENV{TMPDIR} || '/tmp'; + + ## List of possibilities for the system-wide initialization file. + ## The first one found (if any) is used. + ## Normally on a UNIX it will be in a subdirectory of /opt/local/share or + ## /usr/local/share, depending on the local conventions. + ## But /usr/local/lib/latexmk is put in the list for + ## compatibility with older versions of latexmk. + @rc_system_files = (); + foreach ( 'LatexMk', 'latexmkrc' ) { + push @rc_system_files, + ( "/opt/local/share/latexmk/$_", + "/usr/local/share/latexmk/$_", + "/usr/local/lib/latexmk/$_" ); + } + $search_path_separator = ':'; # Separator of elements in search_path + + $dvi_update_signal = $signo{USR1} + if ( defined $signo{USR1} ); # Suitable for xdvi + $ps_update_signal = $signo{HUP} + if ( defined $signo{HUP} ); # Suitable for gv + $pdf_update_signal = $signo{HUP} + if ( defined $signo{HUP} ); # Suitable for gv + ## default document processing programs. + # Viewer update methods: + # 0 => auto update: viewer watches file (e.g., gv) + # 1 => manual update: user must do something: e.g., click on window. + # (e.g., ghostview, MSWIN previewers, acroread under UNIX) + # 2 => send signal. Number of signal in $dvi_update_signal, + # $ps_update_signal, $pdf_update_signal + # 3 => viewer can't update, because it locks the file and the file + # cannot be updated. (acroread under MSWIN) + # 4 => Run command to update. Command in $dvi_update_command, + # $ps_update_command, $pdf_update_command. + $dvi_previewer = 'start xdvi %O %S'; + $dvi_previewer_landscape = 'start xdvi -paper usr %O %S'; + if ( defined $dvi_update_signal ) { + $dvi_update_method = 2; # xdvi responds to signal to update + } else { + $dvi_update_method = 1; + } +# if ( defined $ps_update_signal ) { +# $ps_update_method = 2; # gv responds to signal to update +# $ps_previewer = 'start gv -nowatch'; +# $ps_previewer_landscape = 'start gv -swap -nowatch'; +# } else { +# $ps_update_method = 0; # gv -watch watches the ps file +# $ps_previewer = 'start gv -watch'; +# $ps_previewer_landscape = 'start gv -swap -watch'; +# } + # Turn off the fancy options for gv. Regular gv likes -watch etc + # GNU gv likes --watch etc. User must configure + $ps_update_method = 0; # gv -watch watches the ps file + $ps_previewer = 'start gv %O %S'; + $ps_previewer_landscape = 'start gv -swap %O %S'; + $pdf_previewer = 'start acroread %O %S'; + $pdf_update_method = 1; # acroread under unix needs manual update + $lpr = 'lpr %O %S'; # Assume lpr command prints postscript files correctly + $lpr_dvi = + 'NONE $lpr_dvi variable is not configured to allow printing of dvi files'; + $lpr_pdf = + 'NONE $lpr_pdf variable is not configured to allow printing of pdf files'; + # The $pscmd below holds a command to list running processes. It + # is used to find the process ID of the viewer looking at the + # current output file. The output of the command must include the + # process number and the command line of the processes, since the + # relevant process is identified by the name of file to be viewed. + # Uses: + # 1. In preview_continuous mode, to save running a previewer + # when one is already running on the relevant file. + # 2. With xdvi in preview_continuous mode, xdvi must be + # signalled to make it read a new dvi file. + # + # The following works on Solaris, LINUX, HP-UX, IRIX + # Use -f to get full listing, including command line arguments. + # Use -u $ENV{USER} to get all processes started by current user (not just + # those associated with current terminal), but none of other users' + # processes. + # However, the USER environment variable may not exist. Windows uses + # USERNAME instead. (And this propagates to a situation of + # unix-emulation software running under Windows.) + if ( exists $ENV{USER} ) { + $pscmd = "ps -f -u $ENV{USER}"; + } + elsif ( exists $ENV{USERNAME} ) { + $pscmd = "ps -f -u $ENV{USERNAME}"; + } + else { + $pscmd = "ps -f"; + } + $pid_position = 1; # offset of PID in output of pscmd; first item is 0. + if ( $^O eq "linux" ) { + # Ps on Redhat (at least v. 7.2) appears to truncate its output + # at 80 cols, so that a long command string is truncated. + # Fix this with the --width option. This option works under + # other versions of linux even if not necessary (at least + # for SUSE 7.2). + # However the option is not available under other UNIX-type + # systems, e.g., Solaris 8. + # But (19 Aug 2010), the truncation doesn't happen on RHEL4 and 5, + # unless the output is written to a terminal. So the --width + # option is now unnecessary + # $pscmd = "ps --width 200 -f -u $ENV{USER}"; + } + elsif ( $^O eq "darwin" ) { + # OS-X on Macintosh + # open starts command associated with a file. + # For pdf, this is set by default to OS-X's preview, which is suitable. + # Manual update is simply by clicking on window etc, which is OK. + # For ps, this is set also to preview. This works, but since it + # converts the file to pdf and views the pdf file, it doesn't + # see updates, and a refresh cannot be done. This is far from + # optimal. + # For a full installation of MacTeX, which is probably the most common + # on OS-X, an association is created between dvi files and TeXShop. + # This also converts the file to pdf, so again while it works, it + # does not deal with changed dvi files, as far as I can see. + $pdf_previewer = 'open %S'; + $pdf_update_method = 1; # manual + $dvi_previewer = $dvi_previewer_landscape = 'NONE'; + $ps_previewer = $ps_previewer_landscape = 'NONE'; + # Others + $lpr_pdf = 'lpr %O %S'; + $pscmd = "ps -ww -u $ENV{USER}"; + } +} + +## default parameters +$auto_rc_use = 1; # Whether to read rc files automatically +$max_repeat = 5; # Maximum times I repeat latex. Normally + # 3 would be sufficient: 1st run generates aux file, + # 2nd run picks up aux file, and maybe toc, lof which + # contain out-of-date information, e.g., wrong page + # references in toc, lof and index, and unresolved + # references in the middle of lines. But the + # formatting is more-or-less correct. On the 3rd + # run, the page refs etc in toc, lof, etc are about + # correct, but some slight formatting changes may + # occur, which mess up page numbers in the toc and lof, + # Hence a 4th run is conceivably necessary. + # At least one document class (JHEP.cls) works + # in such a way that a 4th run is needed. + # We allow an extra run for safety for a + # maximum of 5. Needing further runs is + # usually an indication of a problem; further + # runs may not resolve the problem, and + # instead could cause an infinite loop. +$clean_ext = ""; # space separated extensions of files that are + # to be deleted when doing cleanup, beyond + # standard set +$clean_full_ext = ""; # space separated extensions of files that are + # to be deleted when doing cleanup_full, beyond + # standard set and those in $clean_ext +@cus_dep_list = (); # Custom dependency list +@default_files = ( '*.tex' ); # Array of LaTeX files to process when + # no files are specified on the command line. + # Wildcards allowed + # Best used for project specific files. +@default_excluded_files = ( ); + # Array of LaTeX files to exclude when using + # @default_files, i.e., when no files are specified + # on the command line. + # Wildcards allowed + # Best used for project specific files. +$texfile_search = ""; # Specification for extra files to search for + # when no files are specified on the command line + # and the @default_files variable is empty. + # Space separated, and wildcards allowed. + # These files are IN ADDITION to *.tex in current + # directory. + # This variable is obsolete, and only in here for + # backward compatibility. + +$fdb_ext = 'fdb_latexmk'; # Extension for the file for latexmk's + # file-database + # Make it long to avoid possible collisions. +$fdb_ver = 3; # Version number for kind of fdb_file. + +$jobname = ''; # Jobname: as with current tex, etc indicates + # basename of generated files. + # Defined so that --jobname=STRING on latexmk's + # command line has same effect as with current + # tex, etc. (If $jobname is non-empty, then + # the --jobname=... option is used on tex.) +$out_dir = ''; # Directory for output files. + # Cf. --output-directory of current (pdf)latex +$aux_dir = ''; # Directory for aux files (log, aux, etc). + # Cf. --aux-directory of current (pdf)latex in MiKTeX. + + +## default flag settings. +$recorder = 1; # Whether to use recorder option on latex/pdflatex +$silent = 0; # Silence latex's messages? +$silence_logfile_warnings = 0; # Do list warnings in log file +$kpsewhich_show = 0; # Show calls to and results from kpsewhich +$landscape_mode = 0; # default to portrait mode +$analyze_input_log_always = 0; # Always analyze .log for input files in the + # <...> and (...) constructions. Otherwise, only + # do the analysis when fls file doesn't exist or is + # out of date. + +# The following two arrays contain lists of extensions (without +# period) for files that are read in during a (pdf)LaTeX run but that +# are generated automatically from the previous run, as opposed to +# being user generated files (directly or indirectly from a custom +# dependency). These files get two kinds of special treatment: +# 1. In clean up, where depending on the kind of clean up, some +# or all of these generated files are deleted. +# (Note that special treatment is given to aux files.) +# 2. In analyzing the results of a run of (pdf)LaTeX, to +# determine if another run is needed. With an error free run, +# a rerun should be provoked by a change in any source file, +# whether a user file or a generated file. But with a run +# that ends in an error, only a change in a user file during +# the run (which might correct the error) should provoke a +# rerun, but a change in a generated file should not. +# These arrays can be user-configured. + +@generated_exts = ( 'aux', 'bcf', 'fls', 'idx', 'ind', 'lof', 'lot', + 'out', 'toc' ); + # N.B. 'out' is generated by hyperref package + +# Which kinds of file do I have requests to make? +# If no requests at all are made, then I will make dvi file +# If particular requests are made then other files may also have to be +# made. E.g., ps file requires a dvi file +$dvi_mode = 0; # No dvi file requested +$postscript_mode = 0; # No postscript file requested +$pdf_mode = 0; # No pdf file requested to be made by pdflatex + # Possible values: + # 0 don't create pdf file + # 1 to create pdf file by pdflatex + # 2 to create pdf file by ps2pdf + # 3 to create pdf file by dvipdf + # 4 to create pdf file by lualatex + # 5 to create pdf file by xelatex + xdvipdfmx +$view = 'default'; # Default preview is of highest of dvi, ps, pdf +$sleep_time = 2; # time to sleep b/w checks for file changes in -pvc mode +$banner = 0; # Non-zero if we have a banner to insert +$banner_scale = 220; # Original default scale +$banner_intensity = 0.95; # Darkness of the banner message +$banner_message = 'DRAFT'; # Original default message +$do_cd = 0; # Do not do cd to directory of source file. + # Thus behave like latex. +$dependents_list = 0; # Whether to display list(s) of dependencies +$dependents_phony = 0; # Whether list(s) of dependencies includes phony targets + # (as with 'gcc -MP'). +$deps_file = '-'; # File for dependency list output. Default stdout. +$rules_list = 0; # Whether to display list(s) of dependencies +@dir_stack = (); # Stack of pushed directories, each of form of + # pointer to array [ cwd, good_cwd ], where + # good_cwd differs from cwd by being converted + # to native MSWin path when cygwin is used. +$cleanup_mode = 0; # No cleanup of nonessential LaTex-related files. + # $cleanup_mode = 0: no cleanup + # $cleanup_mode = 1: full cleanup + # $cleanup_mode = 2: cleanup except for dvi, + # dviF, pdf, ps, psF & xdv +$cleanup_fdb = 0; # No removal of file for latexmk's file-database +$cleanup_only = 0; # When doing cleanup, do not go on to making files +$cleanup_includes_generated = 0; + # Determines whether cleanup deletes files generated by + # custom dependencies +$cleanup_includes_cusdep_generated = 0; + # Determines whether cleanup deletes files generated by + # (pdf)latex (found from \openout lines in log file). +$diagnostics = 0; +$dvi_filter = ''; # DVI filter command +$ps_filter = ''; # Postscript filter command + +$force_mode = 0; # =1 to force processing past errors +$go_mode = 0; # =1 to force processing regardless of time-stamps + # =2 full clean-up first +$preview_mode = 0; +$preview_continuous_mode = 0; +$printout_mode = 0; # Don't print the file + +$show_time = 0; +@timings = (); +$processing_time1 = processing_time(); + +$use_make_for_missing_files = 0; # Whether to use make to try to make missing files. + +# Do we make view file in temporary then move to final destination? +# (To avoid premature updating by viewer). +$always_view_file_via_temporary = 0; # Set to 1 if viewed file is always + # made through a temporary. +$pvc_view_file_via_temporary = 1; # Set to 1 if only in -pvc mode is viewed + # file made through a temporary. + +# State variables initialized here: + +$updated = 0; # Flags when something has been remade + # Used to allow convenient user message in -pvc mode +$waiting = 0; # Flags whether we are in loop waiting for an event + # Used to avoid unnecessary repeated o/p in wait loop + +# Used for some results of parsing log file: +$reference_changed = 0; +$mult_defined = 0; +$bad_reference = 0; +$bad_citation = 0; + +# Cache of expensive-to-compute state variables, e.g., cwd in form +# fixed to deal with cygwin issues. +%cache = (); +&cache_good_cwd; + +# Set search paths for includes. +# Set them early so that they can be overridden +$BIBINPUTS = $ENV{'BIBINPUTS'}; +if (!$BIBINPUTS) { $BIBINPUTS = '.'; } + +# Convert search paths to arrays: +# If any of the paths end in '//' then recursively search the +# directory. After these operations, @BIBINPUTS should +# have all the directories that need to be searched + +@BIBINPUTS = find_dirs1( $BIBINPUTS ); + + +###################################################################### +###################################################################### +# +# ??? UPDATE THE FOLLOWING!! +# +# We will need to determine whether source files for runs of various +# programs are out of date. In a normal situation, this is done by +# asking whether the times of the source files are later than the +# destination files. But this won't work for us, since a common +# situation is that a file is written on one run of latex, for +# example, and read back in on the next run (e.g., an .aux file). +# Some situations of this kind are standard in latex generally; others +# occur with particular macro packages or with particular +# postprocessors. +# +# The correct criterion for whether a source is out-of-date is +# therefore NOT that its modification time is later than the +# destination file, but whether the contents of the source file have +# changed since the last successful run. This also handles the case +# that the user undoes some changes to a source file by replacing the +# source file by reverting to an earlier version, which may well have +# an older time stamp. Since a direct comparison of old and new files +# would involve storage and access of a large number of backup files, +# we instead use the md5 signature of the files. (Previous versions +# of latexmk used the backup file method, but restricted to the case +# of .aux and .idx files, sufficient for most, but not all, +# situations.) +# +# We will have a database of (time, size, md5) for the relevant +# files. If the time and size of a file haven't changed, then the file +# is assumed not to have changed; this saves us from having to +# determine its md5 signature, which would involve reading the whole +# file, which is naturally time-consuming, especially if network file +# access to a server is needed, and many files are involved, when most +# of them don't change. It is of course possible to change a file +# without changing its size, but then to adjust its timestamp +# to what it was previously; this requires a certain amount of +# perversity. We can safely assume that if the user edits a file or +# changes its contents, then the file's timestamp changes. The +# interesting case is that the timestamp does change, because the file +# has actually been written to, but that the contents do not change; +# it is for this that we use the md5 signature. However, since +# computing the md5 signature involves reading the whole file, which +# may be large, we should avoid computing it more than necessary. +# +# So we get the following structure: +# +# 1. For each relevant run (latex, pdflatex, each instance of a +# custom dependency) we have a database of the state of the +# source files that were last used by the run. +# 2. On an initial startup, the database for a primary tex file +# is read that was created by a previous run of latex or +# pdflatex, if this exists. +# 3. If the file doesn't exist, then the criterion for +# out-of-dateness for an initial run is that it goes by file +# timestamps, as in previous versions of latexmk, with due +# (dis)regard to those files that are known to be generated by +# latex and re-read on the next run. +# 4. Immediately before a run, the database is updated to +# represent the current conditions of the run's source files. +# 5. After the run, it is determined whether any of the source +# files have changed. This covers both files written by the +# run, which are therefore in a dependency loop, and files that +# the user may have updated during the run. (The last often +# happens when latex takes a long time, for a big document, +# and the user makes edits before latex has finished. This is +# particularly prevalent when latexmk is used with +# preview-continuous mode.) +# 6. In the case of latex or pdflatex, the custom dependencies +# must also be checked and redone if out-of-date. +# 7. If any source files have changed, the run is redone, +# starting at step 1. +# 8. There is naturally a limit on the number of reruns, to avoid +# infinite loops from bugs and from pathological or unforeseen +# conditions. +# 9. After the run is done, the run's file database is updated. +# (By hypothesis, the sizes and md5s are correct, if the run +# is successful.) +# 10. To allow reuse of data from previous runs, the file database +# is written to a file after every complete set of passes +# through latex or pdflatex. (Note that there is separate +# information for latex and pdflatex; the necessary +# information won't coincide: Out-of-dateness for the files +# for each program concerns the properties of the files when +# the other program was run, and the set of source files could +# be different, e.g., for graphics files.) +# +# We therefore maintain the following data structures.: +# +# a. For each run (latex, pdflatex, each custom dependency) a +# database is maintained. This is a hash from filenames to a +# reference to an array: [time, size, md5]. The semantics of +# the database is that it represents the state of the source +# files used in the run. During a run it represents the state +# immediately before the run; after a run, with all reruns, it +# represents the state of the files used, modified by having +# the latest timestamps for generated files. +# b. There is a global database for all files, which represents +# the current state. This saves having to recompute the md5 +# signatures of a changed file used in more than one run +# (e.g., latex and pdflatex). +# c. Each of latex and pdflatex has a list of the relevant custom +# dependencies. +# +# In all the following a fdb-hash is a hash of the form: +# filename -> [time, size, md5] +# If a file is found to disappear, its entry is removed from the hash. +# In returns from fdb access routines, a size entry of -1 indicates a +# non-existent file. + + +# List of known rules. Rule types: primary, +# external (calls program), internal (calls routine), cusdep. + +%possible_primaries = ( 'latex' => 'primary', 'pdflatex' => 'primary', + 'lualatex' => 'primary', 'xelatex' => 'primary' ); +%primaries = (); # Hash of rules for primary part of make. Keys are + # currently 'latex', 'pdflatex' or both; also 'lualatex' + # and 'xelatex'. Value is currently irrelevant. + # Use hash for ease of lookup + # Make remove this later, if use rdb_makeB + +# Hashes, whose keys give names of particular kinds of rule. We use +# hashes for ease of lookup. +%possible_one_time = ( 'view' => 1, 'print' => 1, 'update_view' => 1, ); +%requested_filerules = (); # Hash for rules corresponding to requested files. + # The keys are the rulenames and the value is + # currently irrelevant. +%one_time = (); # Hash for requested one-time-only rules, currently + # possible values 'print' and 'view'. + + +%rule_db = (); # Database of all rules: + # Hash: rulename -> [array of rule data] + # Rule data: + # 0: [ cmd_type, ext_cmd, int_cmd, test_kind, + # source, dest, base, + # out_of_date, out_of_date_user, + # time_of_last_run, time_of_last_file_check, + # changed + # last_result, last_message, + # default_extra_generated + # ] + # where + # cmd_type is 'primary', 'external', or 'cusdep' + # ext_cmd is string for associated external command + # with substitutions (%D for destination, %S + # for source, %B for base of current rule, + # %R for base of primary tex file, %T for + # texfile name, %O for options, + # %Y for $aux_dir1, and %Z for $out_dir1 + # int_cmd specifies any internal command to be + # used to implement the application of the + # rule. If this is present, it overrides + # the external command, and it is the + # responsibility of the perl subroutine + # specified in intcmd to execute the + # external command if this is appropriate. + # This variable intcmd is a reference to an array, + # $$intcmd[0] = internal routine + # $$intcmd[1...] = its arguments (if any) + # test_kind specifies method of determining + # whether a file is out-of-date: + # 0 for never + # 1 for usual: whether there is a source + # file change + # 2 for dest earlier than source + # 3 for method 2 at first run, 1 thereafter + # (used when don't have file data from + # previous run). + # source = name of primary source file, if any + # dest = name of primary destination file, + # if any + # base = base name, if any, of files for + # this rule + # out_of_date = 1 if it has been detected that + # this rule needs to be run + # (typically because a source + # file has changed). + # 0 otherwise + # out_of_date_user is like out_of_date, except + # that the detection of out-of-dateness + # has been made from a change of a + # putative user file, i.e., one that is + # not a generated file (e.g., aux). This + # kind of out-of-dateness should provoke a + # rerun whether or not there was an error + # during a run of (pdf)LaTeX. Normally, + # if there is an error, one should wait + # for the user to correct the error. But + # it is possible the error condition is + # already corrected during the run, e.g., + # by the user changing a source file in + # response to an error message. + # time_of_last_run = time that this rule was + # last applied. (In standard units + # from perl, to be directly compared + # with file modification times.) + # time_of_last_file_check = last time that a check + # was made for changes in source files. + # changed flags whether special changes have been made + # that require file-existence status to be ignored + # last_result is + # -1 if no run has been made, + # 0 if the last run was successful + # 1 if last run was successful, but + # failed to create an output file + # 2 if last run failed + # 200 if last run gave a warning that is + # important enough to be reported with + # the error summary. The warning + # message is stored in last_message. + # last_message is error message for last run + # default_extra_generated is a reference to an array + # of specifications of extra generated files (beyond + # the main dest file. Standard place holders are used. + # Example ['%Y%R.log'] for (pdf)latex, and ['%R.blg'] + # for bibtex. (There's no need for '%R.aux', here, + # since such generated files are detected dynamically.) + # 1: {Hash sourcefile -> [source-file data] } + # Source-file data array: + # 0: time + # 1: size + # 2: md5 + # 3: name of rule to make this file + # 4: whether the file is of the kind made by epstopdf.sty + # during a primary run. It will have been read during + # the run, so that even though the file changes during + # a primary run, there is no need to trigger another + # run because of this. + # Size and md5 correspond to the values at the last run. + # But time may be updated to correspond to the time + # for the file, if the file is otherwise unchanged. + # This saves excessive md5 calculations, which would + # otherwise be done everytime the file is checked, + # in the following situation: + # When the file has been rewritten after a run + # has started (commonly aux, bbl files etc), + # but the actual file contents haven't + # changed. Then because the filetime has + # changed, on every file-change check latexmk + # would normally redo the md5 calculation to + # test for actual changes. Once one such + # check is done, and the contents are + # unchanged, later checks are superfluous, and + # can be avoided by changing the file's time + # in the source-file list. + # 2: {Hash generated_file -> 1 } + # This lists all generated files; the values + # are currently unused, only the keys + +%fdb_current = (); # Fdb-hash for all files used. + + +# User's home directory +$HOME = ''; +if (exists $ENV{'HOME'} ) { + $HOME = $ENV{'HOME'}; +} +elsif (exists $ENV{'USERPROFILE'} ) { + $HOME = $ENV{'USERPROFILE'}; +} +# XDG configuration home +$XDG_CONFIG_HOME = ''; +if (exists $ENV{'XDG_CONFIG_HOME'} ) { + $XDG_CONFIG_HOME = $ENV{'XDG_CONFIG_HOME'}; +} +elsif ($HOME ne '') { + if ( -d "$HOME/.config") { + $XDG_CONFIG_HOME = "$HOME/.config"; + } +} + + +#================================================== + +# Options that are to be obeyed before rc files are read: + +foreach $_ ( @ARGV ) +{ + if (/^-{1,2}norc$/ ) { + $auto_rc_use = 0; + } +} + +#================================================== +## Read rc files with this subroutine + +sub read_first_rc_file_in_list { + foreach my $rc_file ( @_ ) { + #print "===Testing for rc file \"$rc_file\" ...\n"; + if ( -d $rc_file ) { + warn "$My_name: I have found a DIRECTORY named \"$rc_file\".\n", + " Have you perhaps misunderstood latexmk's documentation?\n", + " This name is normally used for a latexmk configuration (rc) file,\n", + " and in that case it should be a regular text file, not a directory.\n"; + } + elsif ( -e $rc_file ) { + #print "===Reading rc file \"$rc_file\" ...\n"; + process_rc_file( $rc_file ); + return; + } + } +} + +# Note that each rc file may unset $auto_rc_use to +# prevent lower-level rc files from being read. +# So test on $auto_rc_use in each case. +if ( $auto_rc_use ) { + # System rc file: + read_first_rc_file_in_list( @rc_system_files ); +} +if ( $auto_rc_use && ($HOME ne "" ) ) { + # User rc file: + @user_rc = (); + if ( $XDG_CONFIG_HOME ) { + push @user_rc, "$XDG_CONFIG_HOME/latexmk/latexmkrc"; + } + # N.B. $HOME equals "" if latexmk couldn't determine a home directory. + # In that case, we shouldn't look for an rc file there. + if ( $HOME ) { + push @user_rc, "$HOME/.latexmkrc"; + } + read_first_rc_file_in_list( @user_rc ); +} +if ( $auto_rc_use ) { + # Rc file in current directory: + read_first_rc_file_in_list( "latexmkrc", ".latexmkrc" ); +} + +## Process command line args. +@command_line_file_list = (); +$bad_options = 0; + +while ($_ = $ARGV[0]) +{ + # Make -- and - equivalent at beginning of option, + # but save original for possible use in (pdf)latex command line + $original = $_; + s/^--/-/; + shift; + if ( /^-aux-directory=(.*)$/ || /^-auxdir=(.*)$/ ) { + $aux_dir = $1; + } + elsif (/^-bibtex$/) { $bibtex_use = 2; } + elsif (/^-bibtex-$/) { $bibtex_use = 0; } + elsif (/^-nobibtex$/) { $bibtex_use = 0; } + elsif (/^-bibtex-cond$/) { $bibtex_use = 1; } + elsif (/^-c$/) { $cleanup_mode = 2; $cleanup_fdb = 1; $cleanup_only = 1; } + elsif (/^-C$/ || /^-CA$/ ) { $cleanup_mode = 1; $cleanup_fdb = 1; $cleanup_only = 1; } + elsif (/^-CF$/) { $cleanup_fdb = 1; } + elsif (/^-cd$/) { $do_cd = 1; } + elsif (/^-cd-$/) { $do_cd = 0; } + elsif (/^-commands$/) { &print_commands; exit; } + elsif (/^-d$/) { $banner = 1; } + elsif (/^-dependents$/ || /^-deps$/ || /^-M$/ ) { $dependents_list = 1; } + elsif (/^-nodependents$/ || /^-dependents-$/ || /^-deps-$/) { $dependents_list = 0; } + elsif (/^-deps-out=(.*)$/) { + $deps_file = $1; + $dependents_list = 1; + } + elsif (/^-diagnostics/) { $diagnostics = 1; } + elsif (/^-dvi$/) { $dvi_mode = 1; } + elsif (/^-dvi-$/) { $dvi_mode = 0; } + elsif (/^-f$/) { $force_mode = 1; } + elsif (/^-f-$/) { $force_mode = 0; } + elsif (/^-g$/) { $go_mode = 1; } + elsif (/^-g-$/) { $go_mode = 0; } + elsif (/^-gg$/) { + $go_mode = 2; $cleanup_mode = 1; $cleanup_fdb = 1; $cleanup_only = 0; + } + elsif ( /^-h$/ || /^-help$/ ) { &print_help; exit;} + elsif (/^-jobname=(.*)$/) { + $jobname = $1; + } + elsif (/^-l$/) { $landscape_mode = 1; } + elsif (/^-l-$/) { $landscape_mode = 0; } + elsif (/^-latex=(.*)$/) { + $latex = $1; + } + elsif (/^-latexoption=(.*)$/) { + push @extra_latex_options, $1; + push @extra_pdflatex_options, $1; + push @extra_lualatex_options, $1; + push @extra_xelatex_options, $1; + } + elsif ( /^-logfilewarninglist$/ || /^-logfilewarnings$/ ) + { $silence_logfile_warnings = 0; } + elsif ( /^-logfilewarninglist-$/ || /^-logfilewarnings-$/ ) + { $silence_logfile_warnings = 1; } +# See above for -M + elsif (/^-MF$/) { + if ( $ARGV[0] eq '' ) { + &exit_help( "No file name specified after -MF switch"); + } + $deps_file = $ARGV[0]; + shift; + } + elsif ( /^-MP$/ ) { $dependents_phony = 1; } + elsif (/^-new-viewer$/) { + $new_viewer_always = 1; + } + elsif (/^-new-viewer-$/) { + $new_viewer_always = 0; + } + elsif (/^-norc$/ ) { + $auto_rc_use = 0; + # N.B. This has already been obeyed. + } + elsif ( /^-output-directory=(.*)$/ ||/^-outdir=(.*)$/ ) { + $out_dir = $1; + } + elsif (/^-p$/) { $printout_mode = 1; + $preview_continuous_mode = 0; # to avoid conflicts + $preview_mode = 0; + } + elsif (/^-p-$/) { $printout_mode = 0; } + elsif (/^-pdf$/) { $pdf_mode = 1; } + elsif (/^-pdf-$/) { $pdf_mode = 0; } + elsif (/^-pdfdvi$/){ $pdf_mode = 3; } + elsif (/^-pdflua$/){ $pdf_mode = 4; } + elsif (/^-pdfxe$/) { $pdf_mode = 5; } +# elsif (/^-pdflatex$/) { +# $pdflatex = "pdflatex %O %S"; +# $pdf_mode = 1; +# $dvi_mode = $postscript_mode = 0; +# } + elsif (/^-pdflatex=(.*)$/) { + $pdflatex = $1; + } + elsif (/^-pdfps$/) { $pdf_mode = 2; } + elsif (/^-print=(.*)$/) { + $value = $1; + if ( $value =~ /^dvi$|^ps$|^pdf$|^auto$/ ) { + $print_type = $value; + $printout_mode = 1; + } + else { + &exit_help("$My_name: unknown print type '$value' in option '$_'"); + } + } + elsif (/^-ps$/) { $postscript_mode = 1; } + elsif (/^-ps-$/) { $postscript_mode = 0; } + elsif (/^-pv$/) { $preview_mode = 1; + $preview_continuous_mode = 0; # to avoid conflicts + $printout_mode = 0; + } + elsif (/^-pv-$/) { $preview_mode = 0; } + elsif (/^-pvc$/) { $preview_continuous_mode = 1; + $force_mode = 0; # So that errors do not cause loops + $preview_mode = 0; # to avoid conflicts + $printout_mode = 0; + } + elsif (/^-pvc-$/) { $preview_continuous_mode = 0; } + elsif (/^-recorder$/ ){ $recorder = 1; } + elsif (/^-recorder-$/ ){ $recorder = 0; } + elsif (/^-rules$/ ) { $rules_list = 1; } + elsif (/^-norules$/ || /^-rules-$/ ) { $rules_list = 0; } + elsif (/^-showextraoptions$/) { + print "List of extra latex and pdflatex options recognized by $my_name.\n", + "These are passed as is to (pdf)latex. They may not be recognized by\n", + "particular versions of (pdf)latex. This list is a combination of those\n", + "for TeXLive and MikTeX.\n", + "\n", + "Note that in addition to the options in this list, there are several\n", + "options known to the (pdf)latex programs that are also recognized by\n", + "latexmk and trigger special behavior by latexmk. Since these options\n", + "appear in the main list given by running 'latexmk --help', they do not\n", + "appear in the following list\n", + "NOTE ALSO: Not all of these options are supported by all versions of (pdf)latex.\n", + "\n"; + foreach $option ( sort( keys %allowed_latex_options, keys %allowed_latex_options_with_arg ) ) { + if (exists $allowed_latex_options{$option} ) { print " $allowed_latex_options{$option}\n"; } + if (exists $allowed_latex_options_with_arg{$option} ) { print " $allowed_latex_options_with_arg{$option}\n"; } + } + exit; + } + elsif (/^-silent$/ || /^-quiet$/ ){ $silent = 1; } + elsif (/^-time$/) { $show_time = 1;} + elsif (/^-time-$/) { $show_time = 0;} + elsif (/^-use-make$/) { $use_make_for_missing_files = 1; } + elsif (/^-use-make-$/) { $use_make_for_missing_files = 0; } + elsif (/^-v$/ || /^-version$/) { + print "\n$version_details. Version $version_num\n"; + exit; + } + elsif (/^-verbose$/) { $silent = 0; } + elsif (/^-view=default$/) { $view = "default";} + elsif (/^-view=dvi$/) { $view = "dvi";} + elsif (/^-view=none$/) { $view = "none";} + elsif (/^-view=ps$/) { $view = "ps";} + elsif (/^-view=pdf$/) { $view = "pdf"; } + elsif (/^-lualatex$/) { + $pdf_mode = 4; + $dvi_mode = $postscript_mode = 0; + } + elsif (/^-xelatex$/) { + $pdf_mode = 5; + $dvi_mode = $postscript_mode = 0; + } + elsif (/^-e$/) { + if ( $#ARGV < 0 ) { + &exit_help( "No code to execute specified after -e switch"); + } + execute_code_string( $ARGV[0] ); + shift; + } + elsif (/^-r$/) { + if ( $ARGV[0] eq '' ) { + &exit_help( "No RC file specified after -r switch"); + } + if ( -e $ARGV[0] ) { + process_rc_file( $ARGV[0] ); + } + else { + die "$My_name: RC file [$ARGV[0]] does not exist\n"; + } + shift; + } + elsif (/^-bm$/) { + if ( $ARGV[0] eq '' ) { + &exit_help( "No message specified after -bm switch"); + } + $banner = 1; $banner_message = $ARGV[0]; + shift; + } + elsif (/^-bi$/) { + if ( $ARGV[0] eq '' ) { + &exit_help( "No intensity specified after -bi switch"); + } + $banner_intensity = $ARGV[0]; + shift; + } + elsif (/^-bs$/) { + if ( $ARGV[0] eq '' ) { + &exit_help( "No scale specified after -bs switch"); + } + $banner_scale = $ARGV[0]; + shift; + } + elsif (/^-dF$/) { + if ( $ARGV[0] eq '' ) { + &exit_help( "No dvi filter specified after -dF switch"); + } + $dvi_filter = $ARGV[0]; + shift; + } + elsif (/^-pF$/) { + if ( $ARGV[0] eq '' ) { + &exit_help( "No ps filter specified after -pF switch"); + } + $ps_filter = $ARGV[0]; + shift; + } + elsif ( ( exists( $allowed_latex_options{$_} ) ) + || ( /^(-.+)=/ && exists( $allowed_latex_options_with_arg{$1} ) ) + ) + { + push @extra_latex_options, $original; + push @extra_pdflatex_options, $original; + push @extra_lualatex_options, $original; + push @extra_xelatex_options, $original; + } + elsif (/^-/) { + warn "$My_name: $_ bad option\n"; + $bad_options++; + } + else { + push @command_line_file_list, $_ ; + } +} + +if ( $bad_options > 0 ) { + &exit_help( "Bad options specified" ); +} + +warn "$My_name: This is $version_details, version: $version_num.\n", + unless $silent; + +if ( ($out_dir ne '') && ($aux_dir eq '') ){ + $aux_dir = $out_dir; +} + +# Versions terminating in directory/path separator +$out_dir1 = $out_dir; +$aux_dir1 = $aux_dir; +foreach ( $aux_dir1, $out_dir1 ) { + if ( ($_ ne '') && ! m([\\/\:]$) ) { + $_ .= '/'; + } +} + +# At least one widely package (revtex4-1) generates a bib file +# (which is used in revtex4-1 for putting footnotes in the reference +# list), and bibtex must be run to use it. But latexmk needs to +# determine the existence of the bib file by use of kpsewhich, otherwise +# there is an error. So cope with this situation (and any analogous +# cases by adding the aux_dir to the relevant path search environment +# variables. BIBINPUTS seems to be the only one currently affected. +foreach ( 'BIBINPUTS' ) { + if ( exists $ENV{$_} ) { + $ENV{$_} = $aux_dir.$search_path_separator.$ENV{$_}; + } + else { + $ENV{$_} = $aux_dir.$search_path_separator; + } +} + + +if ($bibtex_use > 1) { + push @generated_exts, 'bbl'; +} + +# For backward compatibility, convert $texfile_search to @default_files +# Since $texfile_search is initialized to "", a nonzero value indicates +# that an initialization file has set it. +if ( $texfile_search ne "" ) { + @default_files = split /\s+/, "*.tex $texfile_search"; +} + +#Glob the filenames command line if the script was not invoked under a +# UNIX-like environment. +# Cases: (1) MS/MSwin native Glob +# (OS detected as MSWin32) +# (2) MS/MSwin cygwin Glob [because we do not know whether +# the cmd interpreter is UNIXy (and does glob) or is +# native MS-Win (and does not glob).] +# (OS detected as cygwin) +# (3) UNIX Don't glob (cmd interpreter does it) +# (Currently, I assume this is everything else) +if ( ($^O eq "MSWin32") || ($^O eq "cygwin") ) { + # Preserve ordering of files + @file_list = glob_list1(@command_line_file_list); +#print "A1:File list:\n"; +#for ($i = 0; $i <= $#file_list; $i++ ) { print "$i: '$file_list[$i]'\n"; } +} +else { + @file_list = @command_line_file_list; +} +@file_list = uniq1( @file_list ); + + +# Check we haven't selected mutually exclusive modes. +# Note that -c overrides all other options, but doesn't cause +# an error if they are selected. +if (($printout_mode && ( $preview_mode || $preview_continuous_mode )) + || ( $preview_mode && $preview_continuous_mode )) +{ + # Each of the options -p, -pv, -pvc turns the other off. + # So the only reason to arrive here is an incorrect inititalization + # file, or a bug. + &exit_help( "Conflicting options (print, preview, preview_continuous) selected"); +} + +if ( @command_line_file_list ) { + # At least one file specified on command line (before possible globbing). + if ( !@file_list ) { + &exit_help( "Wildcards in file names didn't match any files"); + } +} +else { + # No files specified on command line, try and find some + # Evaluate in order specified. The user may have some special + # for wanting processing in a particular order, especially + # if there are no wild cards. + # Preserve ordering of files + my @file_list1 = uniq1( glob_list1(@default_files) ); + my @excluded_file_list = uniq1( glob_list1(@default_excluded_files) ); + # Make hash of excluded files, for easy checking: + my %excl = (); + foreach my $file (@excluded_file_list) { + $excl{$file} = ''; + } + foreach my $file (@file_list1) { + push( @file_list, $file) unless ( exists $excl{$file} ); + } + if ( !@file_list ) { + &exit_help( "No file name specified, and I couldn't find any"); + } +} + +$num_files = $#file_list + 1; +$num_specified = $#command_line_file_list + 1; + +#print "Command line file list:\n"; +#for ($i = 0; $i <= $#command_line_file_list; $i++ ) { print "$i: '$command_line_file_list[$i]'\n"; } +#print "File list:\n"; +#for ($i = 0; $i <= $#file_list; $i++ ) { print "$i: '$file_list[$i]'\n"; } + + +# If selected a preview-continuous mode, make sure exactly one filename was specified +if ($preview_continuous_mode && ($num_files != 1) ) { + if ($num_specified > 1) { + &exit_help( + "Need to specify exactly one filename for ". + "preview-continuous mode\n". + " but $num_specified were specified" + ); + } + elsif ($num_specified == 1) { + &exit_help( + "Need to specify exactly one filename for ". + "preview-continuous mode\n". + " but wildcarding produced $num_files files" + ); + } + else { + &exit_help( + "Need to specify exactly one filename for ". + "preview-continuous mode.\n". + " Since none were specified on the command line, I looked for \n". + " files in '@default_files'.\n". + " But I found $num_files files, not 1." + ); + } +} + +# If selected jobname, can only apply that to one file: +if ( ($jobname ne '') && ($num_files > 1) ) { + &exit_help( + "Need to specify at most one filename if ". + "jobname specified, \n". + " but $num_files were found (after defaults and wildcarding)." + ); +} + + +# Normalize the commands, to have place-holders for source, dest etc: +&fix_cmds; + +# Add common options +add_option( $latex_default_switches, \$latex ); +add_option( $pdflatex_default_switches, \$pdflatex ); +add_option( $lualatex_default_switches, \$lualatex ); +add_option( $xelatex_default_switches, \$xelatex ); + +foreach (@extra_latex_options) { add_option( $_, \$latex ); } +foreach (@extra_pdflatex_options) { add_option( $_, \$pdflatex ); } +foreach (@extra_lualatex_options) { add_option( $_, \$lualatex ); } +foreach (@extra_xelatex_options) { add_option( $_, \$xelatex ); } + + +# If landscape mode, change dvips processor, and the previewers: +if ( $landscape_mode ) +{ + $dvips = $dvips_landscape; + $dvi_previewer = $dvi_previewer_landscape; + $ps_previewer = $ps_previewer_landscape; +} + +if ( $silent ) { + add_option( "$latex_silent_switch", \$latex ); + add_option( "$pdflatex_silent_switch", \$pdflatex ); + add_option( "$lualatex_silent_switch", \$lualatex ); + add_option( "$xelatex_silent_switch", \$xelatex ); + add_option( "$biber_silent_switch", \$biber ); + add_option( "$bibtex_silent_switch", \$bibtex ); + add_option( "$makeindex_silent_switch", \$makeindex ); + add_option( "$dvipdf_silent_switch", \$dvipdf ); + add_option( "$dvips_silent_switch", \$dvips ); + add_option( "$xdvipdfmx_silent_switch", \$xdvipdfmx ); +} + +if ( $recorder ) { + add_option( "-recorder", \$latex, \$pdflatex, \$lualatex, \$xelatex ); +} + +# If the output and/or aux directories are specified, fix the (pdf)latex +# commands to use them. +# N.B. We'll ensure that the directories actually exist only after a +# possible cd to the document directory, since the directories can be +# relative to the document. + +if ( $out_dir ) { + add_option( "-output-directory=\"$out_dir\"", + \$latex, \$pdflatex, \$lualatex, \$xelatex ); +} +if ( $aux_dir && ($aux_dir ne $out_dir) ) { + # N.B. If $aux_dir and $out_dir are the same, then the -output-directory + # option is sufficient, especially because the -aux-directory exists + # only in MiKTeX, not in TeXLive. + add_option( "-aux-directory=\"$aux_dir\"", + \$latex, \$pdflatex, \$lualatex, \$xelatex ); +} + +if ( $jobname ne '' ) { + $jobstring = "--jobname=\"$jobname\""; + add_option( "$jobstring", \$latex, \$lualatex, \$pdflatex, \$xelatex ); +} + +# Which kind of file do we preview? +if ( $view eq "default" ) { + # If default viewer requested, use "highest" of dvi, ps and pdf + # that was requested by user. + # No explicit request means view dvi. + $view = "dvi"; + if ( $postscript_mode ) { $view = "ps"; } + if ( $pdf_mode ) { $view = "pdf"; } +} + +# Make sure we make the kind of file we want to view: +if ($view eq 'dvi') { $dvi_mode = 1; } +if ($view eq 'ps') { $postscript_mode = 1; } +if ( ($view eq 'pdf') && ($pdf_mode == 0) ) { + $pdf_mode = 1; +} + +# Make sure that we make something if all requests are turned off +if ( ! ( $dvi_mode || $pdf_mode || $postscript_mode || $printout_mode) ) { + print "No specific requests made, so default to dvi by latex\n"; + $dvi_mode = 1; +} + +# Set new-style requested rules: +if ( $dvi_mode ) { $requested_filerules{'latex'} = 1; } +if ( $pdf_mode == 1 ) { $requested_filerules{'pdflatex'} = 1; } +elsif ( $pdf_mode == 2 ) { + $requested_filerules{'latex'} = 1; + $requested_filerules{'dvips'} = 1; + $requested_filerules{'ps2pdf'} = 1; +} +elsif ( $pdf_mode == 3 ) { + $requested_filerules{'latex'} = 1; + $requested_filerules{'dvipdf'} = 1; +} +elsif ( $pdf_mode == 4 ) { + $requested_filerules{'lualatex'} = 1; +} +elsif ( $pdf_mode == 5 ) { + $requested_filerules{'xelatex'} = 1; + $requested_filerules{'xdvipdfmx'} = 1; +} +if ( $postscript_mode ) { + $requested_filerules{'latex'} = 1; + $requested_filerules{'dvips'} = 1; +} +if ($print_type eq 'auto') { + if ( $postscript_mode ) { $print_type = 'ps'; } + elsif ( $pdf_mode ) { $print_type = 'pdf'; } + elsif ( $dvi_mode ) { $print_type = 'dvi'; } + else { $print_type = 'none'; } +} +if ( $printout_mode ) { + $one_time{'print'} = 1; + if ($print_type eq 'none'){ + warn "$My_name: You have requested printout, but \$print_type is set to 'none'\n"; + } +} +if ( $preview_continuous_mode || $preview_mode ) { $one_time{'view'} = 1; } +if ( length($dvi_filter) != 0 ) { $requested_filerules{'dvi_filter'} = 1; } +if ( length($ps_filter) != 0 ) { $requested_filerules{'ps_filter'} = 1; } +if ( $banner ) { $requested_filerules{'dvips'} = 1; } + + +if ( $pdf_mode == 2 ) { + # We generate pdf from ps. Make sure we have the correct kind of ps. + add_option( "$dvips_pdf_switch", \$dvips ); +} + +# Note sleep has granularity of 1 second. +# Sleep periods 0 < $sleep_time < 1 give zero delay, +# which is probably not what the user intended. +# Sleep periods less than zero give infinite delay +if ( $sleep_time < 0 ) { + warn "$My_name: Correcting negative sleep_time to 1 sec.\n"; + $sleep_time = 1; +} +elsif ( ($sleep_time < 1) && ( $sleep_time != 0 ) ) { + warn "$My_name: Correcting nonzero sleep_time of less than 1 sec to 1 sec.\n"; + $sleep_time = 1; +} +elsif ( $sleep_time == 0 ) { + warn "$My_name: sleep_time was configured to zero.\n", + " Do you really want to do this? It will give 100% CPU usage.\n"; +} + +# Make convenient forms for lookup. +# Extensions always have period. + +# Convert @generated_exts to a hash for ease of look up and deletion +# Keep extension without period! +%generated_exts_all = (); +foreach (@generated_exts ) { + $generated_exts_all{$_} = 1; +} + +if ($aux_dir) { + # Ensure $aux_dir is in TEXINPUTS search path. + # This is used by dvips for files generated by mpost. + if ( ! exists $ENV{TEXINPUTS} ) { + # Note the trailing ":" which ensures that the last item + # in the list of paths is the empty path, which actually + # means the default path, i.e., the following means that + # the TEXINPUTS search path is $aux_dir and the standard + # value. + $ENV{TEXINPUTS} = $aux_dir.$search_path_separator; + } + elsif ( $ENV{TEXINPUTS} !~ /$aux_dir$search_path_separator/ ) { + $ENV{TEXINPUTS} = $aux_dir.$search_path_separator.$ENV{TEXINPUTS}; + } +} + +$quell_uptodate_msgs = $silent; + # Whether to quell informational messages when files are uptodate + # Will turn off in -pvc mode + +$failure_count = 0; +@failed_primaries = (); + +if ($deps_file eq '' ) { + # Standardize name used for stdout + $deps_file = '-'; +} + +# In non-pvc mode, the dependency list is global to all processed TeX files, +# so we open a single file here, and add items to it after processing each file +# But in -pvc mode, the dependency list should be written after round of +# processing the single TeX file (as if each round were a separate run of +# latexmk). There's undoubtedly some non-optimal structuring here! +if ( $dependents_list && ! $preview_continuous_mode ) { + $deps_handle = new FileHandle "> $deps_file"; + if (! defined $deps_handle ) { + die "Cannot open '$deps_file' for output of dependency information\n"; + } +} + +# Remove leading and trailing space in the following space-separated lists, +# and collapse multiple spaces to one, +# to avoid getting incorrect blank items when they are split. +foreach ($clean_ext, $clean_full_ext) { s/^\s+//; s/\s+$//; s/\s+/ /g; } + + +FILE: +foreach $filename ( @file_list ) +{ + # Global variables for making of current file: + $updated = 0; + $failure = 0; # Set nonzero to indicate failure at some point of + # a make. Use value as exit code if I exit. + $failure_msg = ''; # Indicate reason for failure + + if ( $do_cd ) { + ($filename, $path) = fileparse( $filename ); + warn "$My_name: Changing directory to '$path'\n"; + pushd( $path ); + } + else { + $path = ''; + } + + # Ensure the output/auxiliary directories exist, if need be + if ( $out_dir ) { + if ( ! -e $out_dir ) { + warn "$My_name: making output directory '$out_dir'\n" + if ! $silent; + make_path $out_dir; + } + elsif ( ! -d $out_dir ) { + warn "$My_name: you requested output directory '$out_dir',\n", + " but an ordinary file of the same name exists, which will\n", + " probably give an error later\n"; + } + } + + if ( $aux_dir && ($aux_dir ne $out_dir) ) { + # N.B. If $aux_dir and $out_dir are the same, then the -output-directory + # option is sufficient, especially because the -aux-directory exists + # only in MiKTeX, not in TeXLive. + if ( ! -e $aux_dir ) { + warn "$My_name: making auxiliary directory '$aux_dir'\n" + if ! $silent; + make_path $aux_dir; + } + elsif ( ! -d $aux_dir ) { + warn "$My_name: you requested aux directory '$aux_dir',\n", + " but an ordinary file of the same name exists, which will\n", + " probably give an error later\n"; + } + } + + ## remove extension from filename if was given. + if ( find_basename($filename, $root_filename, $texfile_name) ) + { + if ( $force_mode ) { + warn "$My_name: Could not find file [$texfile_name]\n"; + } + else { + &ifcd_popd; + &exit_msg1( "Could not find file [$texfile_name]", + 11); + } + } + if ($jobname ne '' ) { + $root_filename = $jobname; + } + + $aux_main = "$aux_dir1$root_filename.aux"; + $log_name = "$aux_dir1$root_filename.log"; + $fdb_name = "$aux_dir1$root_filename.$fdb_ext"; + + # Initialize basic dependency information: + + # For use under error conditions: + @default_includes = ($texfile_name, $aux_main); + + # Initialize rule database. + # ?? Should I also initialize file database? + %rule_list = (); + &rdb_make_rule_list; + &rdb_set_rules( \%rule_list, \%extra_rule_spec ); + + if ( $cleanup_mode > 0 ) { +# ?? MAY NEED TO FIX THE FOLLOWING IF $aux_dir or $out_dir IS SET. + my %other_generated = (); + my @index_bibtex_generated = (); + my @aux_files = (); + $have_fdb = 0; + if ( -e $fdb_name ) { + print "$My_name: Examining fdb file '$fdb_name' for rules ...\n" + if $diagnostics; + $have_fdb = ( 0 == rdb_read( $fdb_name ) ); + } + if ( $have_fdb ) { + rdb_for_all( + sub { # Find generated files at rule level + my ($base, $path, $ext) = fileparseA( $$Psource ); + $base = $path.$base; + if ( $rule =~ /^makeindex/ ) { + push @index_bibtex_generated, $$Psource, $$Pdest, "$base.ilg"; + } + elsif ( $rule =~ /^(bibtex|biber)/ ) { + push @index_bibtex_generated, $$Pdest, "$base.blg"; + push @aux_files, $$Psource; + } + elsif ( exists $other_generated{$$Psource} ) { + $other_generated{$$Pdest}; + } + }, + sub { # Find generated files at source file level + if ( $file =~ /\.aux$/ ) { push @aux_files, $file; } + } + ); + } + elsif ( -e $log_name ) { + # No fdb file, but log file exists, so do inferior job by parse_log + print "$My_name: Examining log file '$log_name' for generated files...\n" + if $diagnostics; + # Variables set by parse_log. Can I remove them? + local %generated_log = (); + local %dependents = (); # Maps files to status. Not used here. + local @bbl_files = (); # Not used here. + local %idx_files = (); # Maps idx_file to (ind_file, base). Not used here. + local %conversions = (); # (pdf)latex-performed conversions. Not used here. + # Maps output file created and read by (pdf)latex + # to source file of conversion. + local $primary_out = ''; # Actual output file (dvi or pdf). Not used here. + local $fls_file_analyzed = 0; + &parse_log; + %other_generated = %generated_log; + } + else { + print "$My_name: No fdb or log file, so clean up default set of files ...\n" + if $diagnostics; + } + + if ( ($go_mode == 2) && !$silent ) { + warn "$My_name: Removing all generated files\n" unless $silent; + } + if ($bibtex_use < 2) { + delete $generated_exts_all{'bbl'}; + } + # Convert two arrays to hashes: + my %index_bibtex_generated = (); + my %aux_files = (); + foreach (@index_bibtex_generated) { + $index_bibtex_generated{$_} = 1 + unless ( /\.bbl$/ && ($bibtex_use < 2) ); + delete( $other_generated{$_} ); + } + foreach (@aux_files) { + $aux_files{$_} = 1; + delete( $other_generated{$_} ); + } + if ($diagnostics) { + show_array( "For deletion, the following were determined from fdb file or log file:\n" + ." Generated (from makeindex and bibtex):", + keys %index_bibtex_generated ); + show_array( " Aux files:", keys %aux_files ); + show_array( " Other generated files:\n" + ." (only deleted if \$cleanup_includes_generated is set): ", + keys %other_generated ); + show_array( " Yet other generated files:\n", + keys %generated_exts_all ); + } + &cleanup1( $aux_dir1, $fdb_ext, 'blg', 'ilg', 'log', 'aux.bak', 'idx.bak', + split('\s+',$clean_ext), + keys %generated_exts_all + ); + unlink_or_move( 'texput.log', "texput.aux", "missfont.log", + keys %index_bibtex_generated, + keys %aux_files ); + if ( $dependents_list && ( $deps_file ne '-' ) ) { + unlink_or_move( $deps_file ); + } + if ($cleanup_includes_generated) { + unlink_or_move( keys %other_generated ); + } + if ( $cleanup_includes_cusdep_generated) { + &cleanup_cusdep_generated; + } + if ( $cleanup_mode == 1 ) { + &cleanup1( $out_dir1, 'dvi', 'dviF', 'ps', 'psF', 'pdf', + 'synctex.gz', 'xdv', + split('\s+', $clean_full_ext) + ); + } + } + if ($cleanup_fdb) { + unlink_or_move( $fdb_name ); + # If the fdb file exists, it will have been read, and therefore changed + # rule database. But deleting the fdb file implies we also want + # a virgin rule database, so we must reset it: + rdb_set_rules( \%rule_list ); + } + if ($cleanup_only) { next FILE; } + + +#??? The following are not needed if use rdb_make. +# ?? They may be set too early? +# Arrays and hashes for picking out accessible rules. +# Distinguish rules for making files and others + @accessible_all = sort ( &rdb_accessible( keys %requested_filerules, keys %one_time )); + %accessible_filerules = (); + foreach (@accessible_all) { + unless ( /view/ || /print/ ) { $accessible_filerules{$_} = 1; } + } + @accessible_filerules = sort keys %accessible_filerules; + +# show_array ( "=======All rules used", @accessible_all ); +# show_array ( "=======Requested file rules", sort keys %requested_filerules ); +# show_array ( "=======Rules for files", @accessible_filerules ); + + if ( $diagnostics ) { + print "$My_name: Rules after start up for '$texfile_name'\n"; + rdb_show(); + } + + %primaries = (); + foreach (@accessible_all) { + if ( ($_ eq 'latex') || ($_ eq 'pdflatex') || ($_ eq 'lualatex') + || ($_ eq 'xelatex') ) + { $primaries{$_} = 1; } + } + + $have_fdb = 0; + if (! -e $aux_main ) { + # No aux file => set up trivial aux file + # and corresponding fdb_file. Arrange them to provoke one run + # as minimum, but no more if actual aux file is trivial. + # (Useful on big files without cross references.) + # If aux file doesn't exist, then any fdb file is surely + # wrong. + # Previously, I had condition for this as being both aux and + # fdb files failing to exist. But it's not obvious what to + # do if aux exists and fdb doesn't. So I won't do anything. + &set_trivial_aux_fdb; + } + + if ( -e $fdb_name ) { + $rdb_errors = rdb_read( $fdb_name ); + $have_fdb = ($rdb_errors == 0); + } + if (!$have_fdb) { + # We didn't get a valid set of data on files used in + # previous run. So use filetime criterion for make + # instead of change from previous run, until we have + # done our own make. + rdb_recurse( [keys %possible_primaries], + sub{ if ( $$Ptest_kind == 1 ) { $$Ptest_kind = 3;} } + ); + if ( -e $log_name ) { + rdb_for_some( [keys %possible_primaries], \&rdb_set_latex_deps ); + } + } + foreach $rule ( rdb_accessible( uniq1( keys %requested_filerules ) ) ){ + # For all source files of all accessible rules, + # if the file data are not already set (e.g., from fdb_latexmk + # file, set them from disk. + rdb_one_rule ($rule, undef, + sub{ if ( $$Ptime == 0) { &rdb_update1; } } + ); + } + + if ($go_mode) { + # Force everything to be remade. + rdb_recurse( [keys %requested_filerules], sub{$$Pout_of_date=1;} ); + } + + + if ( $diagnostics ) { + print "$My_name: Rules after initialization\n"; + rdb_show(); + } + + #************************************************************ + + if ( $preview_continuous_mode ) { + &make_preview_continuous; + next FILE; + } + + +## Handling of failures: +## Variable $failure is set to indicate a failure, with information +## put in $failure_msg. +## These variables should be set to 0 and '' at any point at which it +## should be assumed that no failures have occurred. +## When after a routine is called it is found that $failure is set, then +## processing should normally be aborted, e.g., by return. +## Then there is a cascade of returns back to the outermost level whose +## responsibility is to handle the error. +## Exception: An outer level routine may reset $failure and $failure_msg +## after initial processing, when the error condition may get +## ameliorated later. + #Initialize failure flags now. + $failure = 0; + $failure_msg = ''; + $failure = rdb_make( keys %requested_filerules ); + if ( ( $failure <= 0 ) || $force_mode ) { + rdb_for_some( [keys %one_time], \&rdb_run1 ); + } + if ($failure > 0) { next FILE; } +} # end FILE +continue { + if ($deps_handle) { deps_list($deps_handle); } + # If requested, print the list of rules. But don't do this in -pvc + # mode, since the rules list has already been printed. + if ($rules_list && ! $preview_continuous_mode) { rdb_list(); } + # Handle any errors + $error_message_count = rdb_show_rule_errors(); + if ( ($error_message_count == 0) || ($failure > 0) ) { + if ( $failure_msg ) { + #Remove trailing space + $failure_msg =~ s/\s*$//; + warn "$My_name: Did not finish processing file '$filename':\n", + " $failure_msg\n"; + $failure = 1; + } + } + if ( ($failure > 0) || ($error_message_count > 0) ) { + $failure_count ++; + push @failed_primaries, $filename; + } + &ifcd_popd; +} +close($deps_handle) if ( $deps_handle ); + +if ($show_time) { show_timing();} + +sub show_timing { + my $processing_time = processing_time() - $processing_time1; + print @timings, "Accumulated processing time = $processing_time\n"; + @timings = (); + $processing_time1 = processing_time(); +} + +# If we get here without going through the continue section: +if ( $do_cd && ($#dir_stack > -1) ) { + # Just in case we did an abnormal exit from the loop + warn "$My_name: Potential bug: dir_stack not yet unwound, undoing all directory changes now\n"; + &finish_dir_stack; +} + +if ($failure_count > 0) { + if ( $#file_list > 0 ) { + # Error occured, but multiple files were processed, so + # user may not have seen all the error messages + warn "\n------------\n"; + show_array( + "$My_name: Some operations failed, for the following tex file(s)", + @failed_primaries); + } + if ( !$force_mode ) { + warn "$My_name: Use the -f option to force complete processing,\n", + " unless error was exceeding maximum runs of latex/pdflatex.\n"; + } + exit 12; +} + + + +# end MAIN PROGRAM +############################################################# + +sub fix_cmds { + # If commands do not have placeholders for %S etc, put them in + foreach ($latex, $pdflatex, $lpr, $lpr_dvi, $lpr_pdf, + $pdf_previewer, $ps_previewer, $ps_previewer_landscape, + $dvi_previewer, $dvi_previewer_landscape, + $kpsewhich + ) { + # Source only + if ( $_ && ! /%/ ) { $_ .= " %O %S"; } + } + foreach ($pdf_previewer, $ps_previewer, $ps_previewer_landscape, + $dvi_previewer, $dvi_previewer_landscape, + ) { + # Run previewers detached + if ( $_ && ! /^(nostart|NONE|internal) / ) { + $_ = "start $_"; + } + } + foreach ($biber, $bibtex) { + # Base only + if ( $_ && ! /%/ ) { $_ .= " %O %B"; } + } + foreach ($dvipdf, $ps2pdf) { + # Source and dest without flag for destination + if ( $_ && ! /%/ ) { $_ .= " %O %S %D"; } + } + foreach ($dvips, $makeindex) { + # Source and dest with -o dest before source + if ( $_ && ! /%/ ) { $_ .= " %O -o %D %S"; } + } + foreach ($dvi_filter, $ps_filter) { + # Source and dest, but as filters + if ( $_ && ! /%/ ) { $_ .= " %O <%S >%D"; } + } +} #END fix_cmds + +############################################################# + +sub add_option { + # Call add_option( $opt, \$cmd ... ) + # Add option to one or more commands + my $option = shift; + while (@_) { + if ( ${$_[0]} !~ /%/ ) { &fix_cmds; } + ${$_[0]} =~ s/%O/$option %O/; + shift; + } +} #END add_option + +############################################################# + +sub rdb_make_rule_list { +# Set up specifications for standard rules, adjusted to current conditions +# Substitutions: %S = source, %D = dest, %B = this rule's base +# %T = texfile, %R = root = base for latex. +# %Y for $aux_dir1, %Z for $out_dir1 + + # Defaults for dvi, ps, and pdf files + # Use local, not my, so these variables can be referenced + local $dvi_final = "%Z%R.dvi"; + local $ps_final = "%Z%R.ps"; + local $pdf_final = "%Z%R.pdf"; + local $xdv_final = "%Z%R.xdv"; + if ( length($dvi_filter) > 0) { + $dvi_final = "%Z%R.dviF"; + } + if ( length($ps_filter) > 0) { + $ps_final = "%Z%R.psF"; + } + + my $print_file = ''; + my $print_cmd = 'NONE'; + if ( $print_type eq 'dvi' ) { + $print_file = $dvi_final; + $print_cmd = $lpr_dvi; + } + elsif ( $print_type eq 'pdf' ) { + $print_file = $pdf_final; + $print_cmd = $lpr_pdf; + } + elsif ( $print_type eq 'ps' ) { + $print_file = $ps_final; + $print_cmd = $lpr; + } + elsif ( $print_type eq 'none' ) { + $print_cmd = 'NONE echo NO PRINTING CONFIGURED'; + } + + my $view_file = ''; + my $viewer = ''; + my $viewer_update_method = 0; + my $viewer_update_signal = undef; + my $viewer_update_command = undef; + + if ( ($view eq 'dvi') || ($view eq 'pdf') || ($view eq 'ps') ) { + $view_file = ${$view.'_final'}; + $viewer = ${$view.'_previewer'}; + $viewer_update_method = ${$view.'_update_method'}; + $viewer_update_signal = ${$view.'_update_signal'}; + if (defined ${$view.'_update_command'}) { + $viewer_update_command = ${$view.'_update_command'}; + } + } + # Specification of internal command for viewer update: + my $PA_update = ['do_update_view', $viewer_update_method, $viewer_update_signal, 0, 1]; + +# For test_kind: Use file contents for latex and friends, but file time for the others. +# This is because, especially for dvi file, the contents of the file may contain +# a pointer to a file to be included, not the contents of the file! + %rule_list = ( + 'latex' => [ 'primary', "$latex", '', "%T", "%Z%B.dvi", "%R", 1, ["%Y%R.log"] ], + 'pdflatex' => [ 'primary', "$pdflatex", '', "%T", "%Z%B.pdf", "%R", 1, ["%Y%R.log"] ], + 'lualatex' => [ 'primary', "$lualatex", '', "%T", "%Z%B.pdf", "%R", 1, ["%Y%R.log"] ], + 'xelatex' => [ 'primary', "$xelatex", '', "%T", "%Z%B.xdv", "%R", 1, ["%Y%R.log"] ], + 'dvipdf' => [ 'external', "$dvipdf", 'do_viewfile', $dvi_final, "%B.pdf", "%Z%R", 2 ], + 'xdvipdfmx' => [ 'external', "$xdvipdfmx", 'do_viewfile', $xdv_final, "%B.pdf", "%Z%R", 2 ], + 'dvips' => [ 'external', "$dvips", 'do_viewfile', $dvi_final, "%B.ps", "%Z%R", 2 ], + 'dvifilter'=> [ 'external', $dvi_filter, 'do_viewfile', "%B.dvi", "%B.dviF", "%Z%R", 2 ], + 'ps2pdf' => [ 'external', "$ps2pdf", 'do_viewfile', $ps_final, "%B.pdf", "%Z%R", 2 ], + 'psfilter' => [ 'external', $ps_filter, 'do_viewfile', "%B.ps", "%B.psF", "%Z%R", 2 ], + 'print' => [ 'external', "$print_cmd", 'if_source', $print_file, "", "", 2 ], + 'update_view' => [ 'external', $viewer_update_command, $PA_update, + $view_file, "", "", 2 ], + 'view' => [ 'external', "$viewer", 'if_source', $view_file, "", "", 2 ], + ); + +# Ensure we only have one way to make pdf file, and that it is appropriate: + if ($pdf_mode == 2) { delete $rule_list{'dvipdf'}; delete $rule_list{'pdflatex'}; delete $rule_list{'lualatex'}; delete $rule_list{'xelatex'}; } + elsif ($pdf_mode == 3) { delete $rule_list{'pdflatex'}; delete $rule_list{'ps2pdf'}; delete $rule_list{'lualatex'}; delete $rule_list{'xelatex'}; } + elsif ($pdf_mode == 4) { delete $rule_list{'pdflatex'}; delete $rule_list{'ps2pdf'}; delete $rule_list{'dvipdf'}; delete $rule_list{'xelatex'}; } + elsif ($pdf_mode == 5) { delete $rule_list{'pdflatex'}; delete $rule_list{'ps2pdf'}; delete $rule_list{'dvipdf'}; delete $rule_list{'lualatex'}; } + else { # Default is to leave pdflatex + delete $rule_list{'dvipdf'}; delete $rule_list{'ps2pdf'}; delete $rule_list{'lualatex'}; delete $rule_list{'xelatex'}; + } + +} # END rdb_make_rule_list + +#************************************************************ + +sub rdb_set_rules { + # Call rdb_set_rules( \%rule_list, ...) + # Set up rule database from definitions + + # Map of files to rules that MAKE them: + %rule_db = (); + + foreach my $Prule_list (@_) { + foreach my $rule ( keys %$Prule_list) { + my ( $cmd_type, $ext_cmd, $int_cmd, $source, $dest, $base, $test_kind, $PA_extra_gen ) = @{$$Prule_list{$rule}}; + if ( ! $PA_extra_gen ) { $PA_extra_gen = []; } + my $needs_making = 0; + # Substitute in the filename variables, since we will use + # those for determining filenames. But delay expanding $cmd + # until run time, in case of changes. + foreach ($base, $source, $dest, @$PA_extra_gen ) { + s/%R/$root_filename/; + s/%Y/$aux_dir1/; + s/%Z/$out_dir1/; + } + foreach ($source, $dest ) { + s/%B/$base/; + s/%T/$texfile_name/; + } + # print "$rule: $cmd_type, EC='$ext_cmd', IC='$int_cmd', $test_kind,\n", + # " S='$source', D='$dest', B='$base' $needs_making\n"; + rdb_create_rule( $rule, $cmd_type, $ext_cmd, $int_cmd, $test_kind, + $source, $dest, $base, + $needs_making, undef, undef, 1, $PA_extra_gen ); +# !! ?? Last line was +# $needs_making, undef, ($test_kind==1) ); + } + } # End arguments of subroutine + &rdb_make_links; +} # END rdb_set_rules + +#************************************************************ + +sub rdb_make_links { +# ?? Problem if there are multiple rules for getting a file. Notably pdf. +# Which one to choose? + # Create $from_rule if there's a suitable rule. + # Map files to rules: + local %from_rules = (); + rdb_for_all( sub{ if($$Pdest){$from_rules{$$Pdest} = $rule;} } ); +#?? foreach (sort keys %from_rules) {print "D='$_' F='$from_rules{$_}\n";} + rdb_for_all( + 0, + sub{ + # Set from_rule, but only if it isn't set or is invalid. + # Don't forget the biber v. bibtex issue + if ( exists $from_rules{$file} + && ( (!$$Pfrom_rule) || (! exists $rule_db{$$Pfrom_rule} ) ) + ) + { $$Pfrom_rule = $from_rules{$file}; + } + } + ); + rdb_for_all( + 0, + sub{ + if ( exists $from_rules{$file} ) { + $$Pfrom_rule = $from_rules{$file}; + } + if ( $$Pfrom_rule && (! rdb_rule_exists( $$Pfrom_rule ) ) ) { + $$Pfrom_rule = ''; + } +#?? print "$rule: $file, $$Pfrom_rule\n"; + } + ); +} # END rdb_make_links + +#************************************************************ + +sub set_trivial_aux_fdb { + # 1. Write aux file EXACTLY as would be written if the tex file + # had no cross references, etc. I.e., a minimal .aux file. + # 2. Write a corresponding fdb file + # 3. Provoke a run of (pdf)latex (actually of all primaries). + + local *aux_file; + open( aux_file, '>', $aux_main ) + or die "Cannot write file '$aux_main'\n"; + print aux_file "\\relax \n"; + close(aux_file); + + foreach my $rule (keys %primaries ) { + rdb_ensure_file( $rule, $texfile_name ); + rdb_ensure_file( $rule, $aux_main ); + rdb_one_rule( $rule, + sub{ $$Pout_of_date = 1; } + ); + } + &rdb_write( $fdb_name ); +} #END set_trivial_aux_fdb + +#************************************************************ +#### Particular actions +#************************************************************ +#************************************************************ + +sub do_cusdep { + # Unconditional application of custom-dependency + # except that rule is not applied if the source file source + # does not exist, and an error is returned if the dest is not made. + # + # Assumes rule context for the custom-dependency, and that my first + # argument is the name of the subroutine to apply + my $func_name = $_[0]; + my $return = 0; + if ( !-e $$Psource ) { + # Source does not exist. Users of this rule will need to turn + # it off when custom dependencies are reset + if ( !$silent ) { +## ??? Was commented out. 1 Sep. 2008 restored, for cusdep no-file-exists issue + warn "$My_name: In trying to apply custom-dependency rule\n", + " to make '$$Pdest' from '$$Psource'\n", + " the source file has disappeared since the last run\n"; + } + # Treat as successful + } + elsif ( !$func_name ) { + warn "$My_name: Possible misconfiguration or bug:\n", + " In trying to apply custom-dependency rule\n", + " to make '$$Pdest' from '$$Psource'\n", + " the function name is blank.\n"; + } + elsif ( ! defined &$func_name ) { + warn "$My_name: Misconfiguration or bug,", + " in trying to apply custom-dependency rule\n", + " to make '$$Pdest' from '$$Psource'\n", + " function name '$func_name' does not exists.\n"; + } + else { + my $cusdep_ret = &$func_name( $$Pbase ); + if ( defined $cusdep_ret && ($cusdep_ret != 0) ) { + $return = $cusdep_ret; + if ($return) { + warn "Rule '$rule', function '$func_name'\n", + " failed with return code = $return\n"; + } + } + elsif ( !-e $$Pdest ) { + # Destination non-existent, but routine failed to give an error + warn "$My_name: In running custom-dependency rule\n", + " to make '$$Pdest' from '$$Psource'\n", + " function '$func_name' did not make the destination.\n"; + $return = -1; + } + } + return $return; +} # END do_cusdep + +#************************************************************ + +sub do_viewfile { + # Unconditionally make file for viewing, going through temporary file if + # Assumes rule context + + my $return = 0; + my ($base, $path, $ext) = fileparseA( $$Pdest ); + if ( &view_file_via_temporary ) { + if ( $$Pext_cmd =~ /%D/ ) { + my $tmpfile = tempfile1( "${root_filename}_tmp", $ext ); + warn "$My_name: Making '$$Pdest' via temporary '$tmpfile'...\n"; + $return = &Run_subst( undef, undef, undef, undef, $tmpfile ); + move( $tmpfile, $$Pdest ); + } + else { + warn "$My_name is configured to make '$$Pdest' via a temporary file\n", + " but the command template '$$Pext_cmd' does not have a slot\n", + " to set the destination file, so I won't use a temporary file\n"; + $return = &Run_subst(); + } + } + else { + $return = &Run_subst(); + } + return $return; +} #END do_viewfile + +#************************************************************ + +sub do_update_view { + # Update viewer + # Assumes rule context + # Arguments: (method, signal, viewer_process) + + my $return = 0; + + # Although the process is passed as an argument, we'll need to update it. + # So (FUDGE??) bypass the standard interface for the process. + # We might as well do this for all the arguments. + my $viewer_update_method = ${$PAint_cmd}[1]; + my $viewer_update_signal = ${$PAint_cmd}[2]; + my $Pviewer_process = \${$PAint_cmd}[3]; + my $Pneed_to_get_viewer_process = \${$PAint_cmd}[4]; + + if ($viewer_update_method == 2) { + if ($$Pneed_to_get_viewer_process) { + $$Pviewer_process = &find_process_id( $$Psource ); + if ($$Pviewer_process != 0) { + $$Pneed_to_get_viewer_process = 0; + } + } + if ($$Pviewer_process == 0) { + print "$My_name: need to signal viewer for file '$$Psource', but didn't get \n", + " process ID for some reason, e.g., no viewer, bad configuration, bug\n" + if $diagnostics ; + } + elsif ( defined $viewer_update_signal) { + print "$My_name: signalling viewer, process ID $$Pviewer_process ", + "with signal $viewer_update_signal\n" + if $diagnostics ; + kill $viewer_update_signal, $$Pviewer_process; + } + else { + warn "$My_name: viewer is supposed to be sent a signal\n", + " but no signal is defined. Misconfiguration or bug?\n"; + $return = 1; + } + } + elsif ($viewer_update_method == 4) { + if (defined $$Pext_cmd) { + $return = &Run_subst(); + } + else { + warn "$My_name: viewer is supposed to be updated by running a command,\n", + " but no command is defined. Misconfiguration or bug?\n"; + } + } + return $return; +} #END do_update_view + +#************************************************************ + +sub if_source { + # Unconditionally apply rule if source file exists. + # Assumes rule context + if ( -e $$Psource ) { + return &Run_subst(); + } + else { + warn "Needed source file '$$Psource' does not exist.\n"; + return -1; + } +} #END if_source + +#************************************************************ +#### Subroutines +#************************************************************ +#************************************************************ + +sub find_basename { + # Finds the basename of the root file + # Arguments: + # 1 - Filename to breakdown + # 2 - Where to place base file + # 3 - Where to place tex file + # Returns non-zero if tex file does not exist + # + # The rules for determining this depend on the implementation of TeX. + # The variable $extension_treatment determines which rules are used. + + # !!!!!!!! I still need to implement use of kpsewhich to match behavior + # of (pdf)latex correctly. + + local($given_name, $base_name, $ext, $path, $tex_name); + $given_name = $_[0]; + if ( "$extension_treatment" eq "miktex_old" ) { + # Miktex v. 1.20d: + # 1. If the filename has an extension, then use it. + # 2. Else append ".tex". + # 3. The basename is obtained from the filename by + # removing the path component, and the extension, if it + # exists. If a filename has a multiple extension, then + # all parts of the extension are removed. + # 4. The names of generated files (log, aux) are obtained by + # appending .log, .aux, etc to the basename. Note that + # these are all in the CURRENT directory, and the drive/path + # part of the originally given filename is ignored. + # + # Thus when the given filename is "\tmp\a.b.c", the tex + # filename is the same, and the basename is "a". + + ($base_name, $path, $ext) = fileparse( $given_name, '\..*' ); + if ( "$ext" eq "") { $tex_name = "$given_name.tex"; } + else { $tex_name = $given_name; } + $_[1] = $base_name; + $_[2] = $tex_name; + } + elsif ( "$extension_treatment" eq "unix" ) { + # unix (at least TeXLive 2016) => + # A. Finding of tex file: + # 1. If filename.tex exists, use it, + # 2. else if kpsewhich finds filename.tex, use it + # 3. else if filename exists, use it, + # 4. else if kpsewhich finds filename, use it. + # (Probably can unify the above by + # 1'. If kpsewhich finds filename.tex, use result. + # 2'. else if kpsewhich finds filename, use result. + # 3'. else report file not found. + # B. The base filename is obtained by deleting the path + # component and, if an extension exists, the last + # component of the extension, even if the extension is + # null. (A name ending in "." has a null extension.) + # C. The names of generated files (log, aux) are obtained by + # appending .log, .aux, etc to the basename. Note that + # these are all in the CURRENT directory, and the drive/path + # part of the originally given filename is ignored. + # + # Thus when the given filename is "/tmp/a.b.c", there are two + # cases: + # a. /tmp/a.b.c.tex exists. Then this is the tex file, + # and the basename is "a.b.c". + # b. /tmp/a.b.c.tex does not exist. Then the tex file is + # "/tmp/a.b.c", and the basename is "a.b". + # But there are also modifications of this when a file can be + # found by kpsewhich. + + if ( -f "$given_name.tex" ) { + $tex_name = "$given_name.tex"; + } + else { + $tex_name = "$given_name"; + } + ($base_name, $path, $ext) = fileparse( $tex_name, '\.[^\.]*' ); + $_[1] = $base_name; + $_[2] = $tex_name; + } + else { + die "$My_name: Incorrect configuration gives \$extension_treatment=", + "'$extension_treatment'\n"; + } + if ($diagnostics) { + print "Given='$given_name', tex='$tex_name', base='$base_name'\n"; + } + return ! -e $tex_name; +} #END find_basename + +#************************************************************ + +sub make_preview_continuous { + local @changed = (); + local @disappeared = (); + local @no_dest = (); # Non-existent destination files + local @rules_never_run = (); + local @rules_to_apply = (); + + local $failure = 0; + local %rules_applied = (); + local $updated = 0; + + # What to make? + my @targets = keys %requested_filerules; + + $quell_uptodate_msgs = 1; + + local $view_file = ''; + rdb_one_rule( 'view', sub{ $view_file = $$Psource; } ); + + if ( ($view eq 'dvi') || ($view eq 'pdf') || ($view eq 'ps') ) { + warn "Viewing $view\n"; + } + elsif ( $view eq 'none' ) { + warn "Not using a previewer\n"; + $view_file = ''; + } + else { + warn "$My_name: BUG: Invalid preview method '$view'\n"; + exit 20; + } + + my $viewer_running = 0; # No viewer known to be running yet + # Get information from update_view rule + local $viewer_update_method = 0; + # Pointers so we can update the following: + local $Pviewer_process = undef; + local $Pneed_to_get_viewer_process = undef; + rdb_one_rule( 'update_view', + sub{ $viewer_update_method = $$PAint_cmd[1]; + $Pviewer_process = \$$PAint_cmd[3]; + $Pneed_to_get_viewer_process = \$$PAint_cmd[4]; + } + ); + # Note that we don't get the previewer process number from the program + # that starts it; that might only be a script to get things set up and the + # actual previewer could be (and sometimes IS) another process. + + if ( ($view_file ne '') && (-e $view_file) && !$new_viewer_always ) { + # Is a viewer already running? + # (We'll save starting up another viewer.) + $$Pviewer_process = &find_process_id( $view_file ); + if ( $$Pviewer_process ) { + warn "$My_name: Previewer is already running\n" + if !$silent; + $viewer_running = 1; + $$Pneed_to_get_viewer_process = 0; + } + } + + # Loop forever, rebuilding .dvi and .ps as necessary. + # Set $first_time to flag first run (to save unnecessary diagnostics) +CHANGE: + for (my $first_time = 1; 1; $first_time = 0 ) { + my %rules_to_watch = %requested_filerules; + $updated = 0; + $failure = 0; + $failure_msg = ''; + if ( $MSWin_fudge_break && ($^O eq "MSWin32") ) { + # Fudge under MSWin32 ONLY, to stop perl/latexmk from + # catching ctrl/C and ctrl/break, and let it only reach + # downstream programs. See comments at first definition of + # $MSWin_fudge_break. + $SIG{BREAK} = $SIG{INT} = 'IGNORE'; + } + if ($compiling_cmd) { + Run_subst( $compiling_cmd ); + } + $failure = rdb_make( @targets ); + +## warn "=========Viewer PID = $$Pviewer_process; updated=$updated\n"; + + if ( $MSWin_fudge_break && ($^O eq "MSWin32") ) { + $SIG{BREAK} = $SIG{INT} = 'DEFAULT'; + } + # Start viewer if needed. + if ( ($failure > 0) && (! $force_mode) ) { + # No viewer yet + } + elsif ( ($view_file ne '') && (-e $view_file) && $updated && $viewer_running ) { + # A viewer is running. Explicitly get it to update screen if we have to do it: + rdb_one_rule( 'update_view', \&rdb_run1 ); + } + elsif ( ($view_file ne '') && (-e $view_file) && !$viewer_running ) { + # Start the viewer + if ( !$silent ) { + if ($new_viewer_always) { + warn "$My_name: starting previewer for '$view_file'\n", + "------------\n"; + } + else { + warn "$My_name: I have not found a previewer that ", + "is already running. \n", + " So I will start it for '$view_file'\n", + "------------\n"; + } + } + local $retcode = 0; + rdb_one_rule( 'view', sub { $retcode = &rdb_run1;} ); + if ( $retcode != 0 ) { + if ($force_mode) { + warn "$My_name: I could not run previewer\n"; + } + else { + &exit_msg1( "I could not run previewer", $retcode); + } + } + else { + $viewer_running = 1; + $$Pneed_to_get_viewer_process = 1; + } # end analyze result of trying to run viewer + } # end start viewer + if ( $failure > 0 ) { + if ( !$failure_msg ) { + $failure_msg = 'Failure to make the files correctly'; + } + @pre_primary = (); # Array of rules + @post_primary = (); # Array of rules + @unusual_one_time = (); # Array of rules + &rdb_classify_rules( \%possible_primaries, keys %requested_filerules ); + # There will be files changed during the run that are irrelevant. + # We need to wait for the user to change the files. + + # So set the GENERATED files from (pdf)latex as up-to-date: + rdb_for_some( [keys %current_primaries], \&rdb_update_gen_files ); + + # And don't watch for changes for post_primary rules (ps and pdf + # from dvi, etc haven't been run after an error in (pdf)latex, so + # are out-of-date by filetime criterion, but they should not be run + # until after another (pdf)latex run: + foreach (@post_primary) { delete $rules_to_watch{$_}; } + + $failure_msg =~ s/\s*$//; #Remove trailing space + warn "$My_name: $failure_msg\n", + " ==> You will need to change a source file before I do another run <==\n"; + if ($failure_cmd) { + Run_subst( $failure_cmd ); + } + } + else { + if ($success_cmd) { + Run_subst( $success_cmd ); + } + } + rdb_show_rule_errors(); + if ($rules_list) { rdb_list(); } + if ($show_time && ! $first_time) { show_timing(); } + if ( $dependents_list && ($updated || $failure) ) { + my $deps_handle = new FileHandle "> $deps_file"; + if ( defined $deps_handle ) { + deps_list($deps_handle); + close($deps_handle); + } + else { + warn "Cannot open '$deps_file' for output of dependency information\n"; + } + } + if ( $first_time || $updated || $failure ) { + print "\n=== Watching for updated files. Use ctrl/C to stop ...\n"; + } + $waiting = 1; if ($diagnostics) { warn "WAITING\n"; } +# During waiting for file changes, handle ctrl/C and ctrl/break here, rather than letting +# system handle them by terminating script (and any script that calls it). This allows, +# for example, the clean up code in the following command line to work: +# latexmk -pvc foo; cleanup; + &catch_break; + $have_break = 0; + WAIT: while (1) { + sleep( $sleep_time ); + if ($have_break) { last WAIT; } + if ( rdb_new_changes(keys %rules_to_watch) ) { + if (!$silent) { + warn "$My_name: Need to remake files.\n"; + &rdb_diagnose_changes( ' ' ); + } + last WAIT; + } + # Don't count waiting time in processing: + $processing_time1 = processing_time(); + # Does this do this job???? + local $new_files = 0; + rdb_for_some( [keys %current_primaries], sub{ $new_files += &rdb_find_new_files } ); + if ($new_files > 0) { + warn "$My_name: New file(s) found.\n"; + last WAIT; + } + if ($have_break) { last WAIT; } + } # end WAIT: + &default_break; + if ($have_break) { + print "$My_name: User typed ctrl/C or ctrl/break. I'll finish.\n"; + return; + } + $waiting = 0; if ($diagnostics) { warn "NOT WAITING\n"; } + } #end infinite_loop CHANGE: +} #END sub make_preview_continuous + +#************************************************************ + +sub process_rc_file { + # Usage process_rc_file( filename ) + # NEW VERSION + # Run rc_file whose name is given in first argument + # Exit with code 0 on success + # Exit with code 1 if file cannot be read or does not exist. + # Stop if there is a syntax error or other problem. + # PREVIOUSLY: + # Exit with code 2 if is a syntax error or other problem. + my $rc_file = $_[0]; + my $ret_code = 0; + warn "$My_name: Executing Perl code in file '$rc_file'...\n" + if $diagnostics; + # I could use the do command of perl, but the preceeding -r test + # to get good diagnostics gets the wrong result under cygwin + # (e.g., on /cygdrive/c/latexmk/LatexMk) + my $RCH = new FileHandle; + if ( !-e $rc_file ) { + warn "$My_name: The rc-file '$rc_file' does not exist\n"; + return 1; + } + elsif ( -d $rc_file ) { + warn "$My_name: The supposed rc-file '$rc_file' is a directory; but it\n", + " should be a normal text file\n"; + return 1; + } + elsif ( open $RCH, "<$rc_file" ) { + { local $/; eval <$RCH>; } + close $RCH; + } + else { + warn "$My_name: I cannot read the rc-file '$rc_file'\n"; + return 1; + } + # PREVIOUS VERSION +# if ( ! -r $rc_file ) { +# warn "$My_name: I cannot read the rc-file '$rc_file'\n", +# " or at least that's what Perl (for $^O) reports\n"; +# return 1; +# } +# do( $rc_file ); + if ( $@ ) { + # Indent each line of possibly multiline message: + my $message = prefix( $@, " " ); + warn "$My_name: Initialization file '$rc_file' gave an error:\n", + "$message\n"; + die "$My_name: Stopping because of problem with rc file\n"; + # Use the following if want non-fatal error. + return 2; + } + return 0; +} #END process_rc_file + +#************************************************************ + +sub execute_code_string { + # Usage execute_code_string( string_of_code ) + # Run the perl code contained in first argument + # Halt if there is a syntax error or other problem. + # ???Should I leave the exiting to the caller (perhaps as an option)? + # But I can always catch it with an eval if necessary. + # That confuses ctrl/C and ctrl/break handling. + my $code = $_[0]; + warn "$My_name: Executing initialization code specified by -e:\n", + " '$code'...\n" + if $diagnostics; + eval $code; + # The return value from the eval is not useful, since it is the value of + # the last expression evaluated, which could be anything. + # The correct test of errors is on the value of $@. + + if ( $@ ) { + # Indent each line of possibly multiline message: + my $message = prefix( $@, " " ); + die "$My_name: ", + "Stopping because executing following code from command line\n", + " $code\n", + "gave an error:\n", + "$message\n"; + } +} #END execute_code_string + +#************************************************************ + +sub cleanup1 { + # Usage: cleanup1( directory, exts_without_period, ... ) + # + # The directory and the root file name are fixed names, so I must escape + # any glob metacharacters in them: + my $dir = fix_pattern( shift ); + my $root_fixed = fix_pattern( $root_filename ); + foreach (@_) { + (my $name = /%R/ ? $_ : "%R.$_") =~ s/%R/$dir$root_fixed/; + unlink_or_move( glob( "$name" ) ); + } +} #END cleanup1 + +#************************************************************ + +sub cleanup_cusdep_generated { + # Remove files generated by custom dependencies + rdb_for_all( \&cleanup_one_cusdep_generated ); +} #END cleanup_cusdep_generated + +#************************************************************ + +sub cleanup_one_cusdep_generated { + # Remove destination file generated by one custom dependency + # Assume rule context, but not that the rule is a custom dependency. + # Only delete destination file if source file exists (so destination + # file can be recreated) + if ( $$Pcmd_type ne 'cusdep' ) { + # NOT cusdep + return; + } + if ( (-e $$Pdest) && (-e $$Psource) ) { + unlink_or_move( $$Pdest ); + } + elsif ( (-e $$Pdest) && (!-e $$Psource) ) { + warn "$My_name: For custom dependency '$rule',\n", + " I won't delete destination file '$$Pdest'\n", + " because the source file '$$Psource' doesn't exist,\n", + " so the destination file may not be able to be recreated\n"; + } +} #END cleanup_one_cusdep_generated + +#************************************************************ +#************************************************************ +#************************************************************ + +# Error handling routines, warning routines, help + +#************************************************************ + +sub die_trace { + # Call: die_trace( message ); + &traceback; # argument(s) passed unchanged + die "\n"; +} #END die_trace + +#************************************************************ + +sub traceback { + # Call: &traceback + # or traceback( message, ) + my $msg = shift; + if ($msg) { warn "$msg\n"; } + warn "Traceback:\n"; + my $i=0; # Start with immediate caller + while ( my ($pack, $file, $line, $func) = caller($i++) ) { + if ($func eq 'die_trace') { next; } + warn " $func called from line $line\n"; + } +} #END traceback + +#************************************************************ + +sub exit_msg1 +{ + # exit_msg1( error_message, retcode [, action]) + # 1. display error message + # 2. if action set, then restore aux file + # 3. exit with retcode + warn "\n------------\n"; + warn "$My_name: $_[0].\n"; + warn "-- Use the -f option to force complete processing.\n"; + + my $retcode = $_[1]; + if ($retcode >= 256) { + # Retcode is the kind returned by system from an external command + # which is 256 * command's_retcode + $retcode /= 256; + } + exit $retcode; +} #END exit_msg1 + +#************************************************************ + +sub warn_running { + # Message about running program: + if ( $silent ) { + warn "$My_name: @_\n"; + } + else { + warn "------------\n@_\n------------\n"; + } +} #END warn_running + +#************************************************************ + +sub exit_help +# Exit giving diagnostic from arguments and how to get help. +{ + warn "\n$My_name: @_\n", + "Use\n", + " $my_name -help\nto get usage information\n"; + exit 10; +} #END exit_help + + +#************************************************************ + +sub print_help +{ + print + "$My_name $version_num: Automatic LaTeX document generation routine\n\n", + "Usage: $my_name [latexmk_options] [filename ...]\n\n", + " Latexmk_options:\n", + " -aux-directory=dir or -auxdir=dir \n", + " - set name of directory for auxiliary files (aux, log)\n", + " - Currently this only works with MiKTeX\n", + " -bibtex - use bibtex when needed (default)\n", + " -bibtex- - never use bibtex\n", + " -bibtex-cond - use bibtex when needed, but only if the bib files exist\n", + " -bm - Print message across the page when converting to postscript\n", + " -bi - Set contrast or intensity of banner\n", + " -bs - Set scale for banner\n", + " -commands - list commands used by $my_name for processing files\n", + " -c - clean up (remove) all nonessential files, except\n", + " dvi, ps and pdf files.\n", + " This and the other clean-ups are instead of a regular make.\n", + " -C - clean up (remove) all nonessential files\n", + " including aux, dep, dvi, postscript and pdf files\n", + " and file of database of file information\n", + " -CA - clean up (remove) all nonessential files.\n", + " Equivalent to -C option.\n", + " -CF - Remove file of database of file information before doing \n", + " other actions\n", + " -cd - Change to directory of source file when processing it\n", + " -cd- - Do NOT change to directory of source file when processing it\n", + " -dependents or -deps - Show list of dependent files after processing\n", + " -dependents- or -deps- - Do not show list of dependent files\n", + " -deps-out=file - Set name of output file for dependency list,\n", + " and turn on showing of dependency list\n", + " -dF - Filter to apply to dvi file\n", + " -dvi - generate dvi\n", + " -dvi- - turn off required dvi\n", + " -e - Execute specified Perl code (as part of latexmk start-up\n", + " code)\n", + " -f - force continued processing past errors\n", + " -f- - turn off forced continuing processing past errors\n", + " -gg - Super go mode: clean out generated files (-CA), and then\n", + " process files regardless of file timestamps\n", + " -g - process regardless of file timestamps\n", + " -g- - Turn off -g\n", + " -h - print help\n", + " -help - print help\n", + " -jobname=STRING - set basename of output file(s) to STRING.\n", + " (Like --jobname=STRING on command line for many current\n", + " implementations of latex/pdflatex.)\n", + " -l - force landscape mode\n", + " -l- - turn off -l\n", + " -latex= - set program used for latex.\n", + " (replace '' by the program name)\n", + " -latexoption=