1 %{ 2 3 /* 4 csound_pre.l: 5 6 Copyright (C) 2011 7 John ffitch 8 9 This file is part of Csound. 10 11 The Csound Library is free software; you can redistribute it 12 and/or modify it under the terms of the Foundation; either 13 version 2.1 of the License, or (at your option) any later version. 14 15 Csound is distributed in the hope that it will be useful, 16 but WITHOUT ANY WARRANTY; without even the implied warranty of 17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 GNU Lesser General Public License for more details. 19 20 You should have received a copy of the GNU Lesser General Public 21 License along with Csound; if not, write to the Free Software 22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MAc 23 02110-1301 USA 24 */ 25 26 #include <stdio.h> 27 #include <string.h> 28 #include <stdlib.h> 29 #include <ctype.h> 30 #include "csoundCore.h" 31 #include "corfile.h" 32 #include <inttypes.h> 33 #define YY_DECL int yylex (CSOUND *csound, yyscan_t yyscanner) 34 static void comment(yyscan_t); 35 static void do_comment(yyscan_t); 36 static void do_include(CSOUND *, int, yyscan_t); 37 static void do_new_include(CSOUND *, yyscan_t); 38 static void do_macro_arg(CSOUND *, char *, yyscan_t); 39 static void do_macro(CSOUND *, char *, yyscan_t); 40 static void do_umacro(CSOUND *, char *, yyscan_t); 41 static void do_umacroq(CSOUND *, char *, yyscan_t); 42 static void do_ifdef(CSOUND *, char *, yyscan_t); 43 static void do_ifdef_skip_code(CSOUND *, yyscan_t); 44 static void do_function(CSOUND*, char *, CORFIL*); 45 //static void print_csound_predata(CSOUND *,char *,yyscan_t); 46 static void csound_pre_line(CSOUND *, CORFIL*, yyscan_t); 47 //static void delete_macros(CSOUND*, yyscan_t); 48 #include "parse_param.h" 49 50 #define YY_EXTRA_TYPE PRE_PARM * 51 #define PARM yyget_extra(yyscanner) 52 53 #define YY_USER_INIT {csound_pre_scan_string(csound->orchstr->body, yyscanner); \ 54 csound_preset_lineno(csound->orcLineOffset, yyscanner); \ 55 yyg->yy_flex_debug_r=1; PARM->macro_stack_size = 0; \ 56 PARM->alt_stack = NULL; PARM->macro_stack_ptr = 0; \ 57 PARM->path = "."; \ 58 } 59 static MACRO *find_definition(MACRO *, char *); 60 61 #define S_INC (10) 62 63 %} 64 %option reentrant 65 %option noyywrap 66 %option prefix="csound_pre" 67 %option outfile="Engine/csound_prelex.c" 68 %option stdout 69 70 NEWLINE (\n|\r\n?) 71 STSTR \" 72 ESCAPE \\. 73 XSTR \{\{([^}]|\}[^}])*\}\} 74 IDENT [a-zA-Z_][a-zA-Z0-9_]* 75 MACRONAME "$"`?[a-zA-Z_][a-zA-Z0-9_`]* 76 MACRONAMED "$"`?[a-zA-Z_][a-zA-Z0-9_`]*\. 77 MACRONAMEA "$"`?[a-zA-Z_][a-zA-Z0-9_`]*\( 78 MACRONAMEDA "$"`?[a-zA-Z_][a-zA-Z0-9_`]*\.\( 79 MACROB [a-zA-Z_][a-zA-Z0-9_]*\( 80 MACRO [a-zA-Z_][a-zA-Z0-9_]* 81 82 STCOM \/\* 83 INCLUDE "#include" 84 INCLUDESTR "#includestr" 85 DEFINE #[ \t]*define 86 UNDEF "#undef" 87 IFDEF #ifn?def 88 ELSE #else[ \t]*(;.*)?$ 89 END #end(if)?[ \t]*(;.*)? 90 CONT \\[ \t]*(;.*)?(\n|\r\n?) 91 RESET "###\n" 92 93 INT "int"[ \t]*\( 94 FRAC "frac"[ \t]*\( 95 ROUND "round"[ \t]*\( 96 FLOOR "floor"[ \t]*\( 97 CEIL "ceil"[ \t]*\( 98 RND "rnd"[ \t]*\( 99 BIRND "birnd"[ \t]*\( 100 ABS "abs"[ \t]*\( 101 EXP "exp"[ \t]*\( 102 LOG "log"[ \t]*\( 103 SQRT "sqrt"[ \t]*\( 104 SIN "sin"[ \t]*\( 105 COS "cos"[ \t]*\( 106 TAN "tan"[ \t]*\( 107 SININV "sininv"[ \t]*\( 108 COSINV "cosinv"[ \t]*\( 109 TANINV "taninv"[ \t]*\( 110 LOG10 "log10"[ \t]*\( 111 LOG2 "log2"[ \t]*\( 112 SINH "sinh"[ \t]*\( 113 COSH "cosh"[ \t]*\( 114 TANH "tanh"[ \t]*\( 115 AMPDB "ampdb"[ \t]*\( 116 AMPDBFS "ampdbfs"[ \t]*\( 117 DBAMP "dbamp"[ \t]*\( 118 DBFSAMP "dbfsamp"[ \t]*\( 119 FTCPS "ftcps"[ \t]*\( 120 FTLEN "ftlen"[ \t]*\( 121 FTSR "ftsr"[ \t]*\( 122 FTLPTIM "ftlptim"[ \t]*\( 123 FTCHNLS "ftchnls"[ \t]*\( 124 I "i"[ \t]*\( 125 K "k"[ \t]*\( 126 CPSOCT "cpsoct"[ \t]*\( 127 OCTPCH "octpch"[ \t]*\( 128 CPSPCH "cpspch"[ \t]*\( 129 PCHOCT "pchoct"[ \t]*\( 130 OCTCPS "octcps"[ \t]*\( 131 NSAMP "nsamp"[ \t]*\( 132 POWOFTWO "powoftwo"[ \t]*\( 133 LOGBTWO "logbtwo"[ \t]*\( 134 A "a"[ \t]*\( 135 TB0 "tb0"[ \t]*\( 136 TB1 "tb1"[ \t]*\( 137 TB2 "tb2"[ \t]*\( 138 TB3 "tb3"[ \t]*\( 139 TB4 "tb4"[ \t]*\( 140 TB5 "tb5"[ \t]*\( 141 TB6 "tb6"[ \t]*\( 142 TB7 "tb7"[ \t]*\( 143 TB8 "tb8"[ \t]*\( 144 TB9 "tb9"[ \t]*\( 145 TB10 "tb10"[ \t]*\( 146 TB11 "tb11"[ \t]*\( 147 TB12 "tb12"[ \t]*\( 148 TB13 "tb13"[ \t]*\( 149 TB14 "tb14"[ \t]*\( 150 TB15 "tb15"[ \t]*\( 151 URD "urd"[ \t]*\( 152 NOT "not"[ \t]*\( 153 CENT "cent"[ \t]*\( 154 OCTAVE "octave"[ \t]*\( 155 SEMITONE "semitone"[ \t]*\( 156 CPSMIDIN "cpsmidinn"[ \t]*\( 157 OCTMIDIN "octmidinn"[ \t]*\( 158 PCHMIDIN "pchmidinn"[ \t]*\( 159 DB "db"[ \t]*\( 160 P "p"[ \t]*\( 161 QINF "qinf"[ \t]*\( 162 QNAN "qnan"[ \t]*\( 163 164 %X incl 165 %x macro 166 %x umacro 167 %x ifdef 168 169 %% 170 171 {RESET} { csound_preset_lineno(csound->orcLineOffset, yyscanner); 172 csound->Free(csound, PARM->alt_stack); 173 } 174 {CONT} { 175 char bb[80]; 176 csound_preset_lineno(1+csound_preget_lineno(yyscanner), 177 yyscanner); 178 if (PARM->isString==0) { 179 sprintf(bb, "#sline %d ", csound_preget_lineno(yyscanner)); 180 corfile_puts(csound, bb, csound->expanded_orc); 181 } 182 } 183 {NEWLINE} { 184 corfile_putc(csound, '\n', csound->expanded_orc); 185 csound_preset_lineno(1+csound_preget_lineno(yyscanner), 186 yyscanner); 187 csound_pre_line(csound, csound->expanded_orc, yyscanner); 188 } 189 "//" { 190 if (PARM->isString != 1) { 191 comment(yyscanner); 192 corfile_putc(csound, '\n', csound->expanded_orc); 193 csound_pre_line(csound, csound->expanded_orc, yyscanner); 194 } 195 else { 196 corfile_puts(csound, yytext, csound->expanded_orc); 197 } 198 } 199 ";" { 200 if (PARM->isString != 1) { 201 comment(yyscanner); 202 corfile_putc(csound, '\n', csound->expanded_orc); 203 csound_pre_line(csound, csound->expanded_orc, yyscanner); 204 } 205 else { 206 corfile_puts(csound, yytext, csound->expanded_orc); 207 } 208 //corfile_putline(csound_preget_lineno(yyscanner), 209 // csound->expanded_orc); 210 } 211 {STCOM} { 212 if (PARM->isString != 1) 213 do_comment(yyscanner); 214 else 215 corfile_puts(csound, yytext, csound->expanded_orc); 216 } 217 {ESCAPE} { corfile_puts(csound, yytext, csound->expanded_orc); } 218 {STSTR} { 219 corfile_putc(csound, '"', csound->expanded_orc); 220 PARM->isString = !PARM->isString; 221 if (PARM->isinclude && PARM->isString==0) { 222 do_new_include(csound, yyscanner); 223 PARM->isinclude = 0; 224 } 225 } 226 {XSTR} { 227 char c, *str = yytext; 228 if (PARM->isString == 1) 229 yyless(2); 230 while ((c = *str++) != '\0') { 231 switch(c) { 232 case '\r': if (*str == '\n') continue; 233 case '\n': 234 csound_preset_lineno(1+csound_preget_lineno(yyscanner), 235 yyscanner); 236 break; 237 default: break; 238 } 239 } 240 corfile_puts(csound, yytext, csound->expanded_orc); 241 } 242 {MACRONAME}|{MACRONAMED} { 243 MACRO *mm = csound->orc_macros; 244 //printf("macro name >>%s<<\n", yytext); 245 mm = find_definition(mm, yytext+1); 246 if (UNLIKELY(mm == NULL)) { 247 csound->Message(csound,Str("Undefined macro: '%s'"), yytext); 248 //csound->LongJmp(csound, 1); 249 corfile_puts(csound, "$error", csound->expanded_orc); 250 } 251 else { 252 /* Need to read from macro definition */ 253 if (UNLIKELY(PARM->macro_stack_ptr +1 >= 254 PARM->macro_stack_size )) { 255 PARM->alt_stack = 256 (MACRON*) 257 csound->ReAlloc(csound, PARM->alt_stack, 258 sizeof(MACRON)* 259 (PARM->macro_stack_size+=S_INC)); 260 if (UNLIKELY(PARM->alt_stack == NULL)) { 261 csound->Message(csound, Str("Memory exhausted")); 262 csound->LongJmp(csound, 1); 263 } 264 } 265 PARM->alt_stack[PARM->macro_stack_ptr].n = 0; 266 PARM->alt_stack[PARM->macro_stack_ptr].line = 267 csound_preget_lineno(yyscanner); 268 PARM->alt_stack[PARM->macro_stack_ptr].path = NULL; 269 PARM->alt_stack[PARM->macro_stack_ptr++].s = NULL; 270 yypush_buffer_state(YY_CURRENT_BUFFER, yyscanner); 271 csound_preset_lineno(1, yyscanner); 272 if (UNLIKELY(PARM->depth>1022)) { 273 csound->Message(csound, 274 Str("macros/include nested too deep: ")); 275 csound->LongJmp(csound, 1); 276 } 277 PARM->lstack[++PARM->depth] = 278 (strchr(mm->body,'\n') ?file_to_int(csound, yytext) : 63); 279 yy_scan_string(mm->body, yyscanner); 280 /* csound->DebugMsg(csound,"%p\n", YY_CURRENT_BUFFER); */ 281 } 282 } 283 {MACRONAMEA}|{MACRONAMEDA} { 284 MACRO *mm = csound->orc_macros; 285 int err = 0; 286 char *mname; 287 int c, i, j, cnt=0; 288 //csound->DebugMsg(csound,"Macro with arguments call %s\n", 289 // yytext); 290 yytext[yyleng-1] = '\0'; 291 mm = find_definition(csound->orc_macros, yytext+1); 292 if (UNLIKELY(mm == NULL)) { 293 csound->Message(csound,Str("Undefined macro: '%s'"), yytext); 294 corfile_puts(csound, "$error", csound->expanded_orc); 295 } 296 else { 297 mname = yytext; 298 /* Need to read from macro definition */ 299 csound->DebugMsg(csound,"Looking for %d args\n", mm->acnt); 300 for (j = 0; j < mm->acnt; j++) { 301 char term = (j == mm->acnt - 1 ? ')' : '\''); 302 /* Compatability */ 303 char trm1 = (j == mm->acnt - 1 ? ')' : '#'); 304 MACRO *nn = (MACRO*) csound->Malloc(csound, sizeof(MACRO)); 305 int size = 100; 306 if (UNLIKELY(nn == NULL)) { 307 csound->Message(csound, Str("Memory exhausted")); 308 csound->LongJmp(csound, 1); 309 } 310 nn->name = csound->Malloc(csound, strlen(mm->arg[j]) + 1); 311 if (UNLIKELY(nn->name == NULL)) { 312 csound->Message(csound, Str("Memory exhausted")); 313 csound->LongJmp(csound, 1); 314 } 315 csound->DebugMsg(csound,"Arg %d: %s\n", j+1, mm->arg[j]); 316 strcpy(nn->name, mm->arg[j]); 317 csound->Message(csound, "defining argument %s ", 318 nn->name); 319 i = 0; 320 nn->body = (char*) csound->Malloc(csound, 100); 321 if (UNLIKELY(nn->body == NULL)) { 322 csound->Message(csound, Str("Memory exhausted")); 323 csound->LongJmp(csound, 1); 324 } 325 while (1) { 326 c = input(yyscanner); 327 if (cnt==0 && ( c==term || c==trm1)) break; 328 if (UNLIKELY(cnt==0 && c == ')')) { 329 csound->Message(csound, 330 Str("Too few arguments to macro\n")); 331 corfile_puts(csound, "$error", csound->expanded_orc); 332 err = 1; break; 333 } 334 if (c=='(') cnt++; 335 if (c==')') cnt--; 336 if (c == '\\') { 337 int newc = input(yyscanner); 338 if (newc == ')') 339 nn->body[i++] = c; 340 c = newc; 341 } 342 if (UNLIKELY(i > 98)) { 343 csound->Message(csound, 344 Str("Missing argument " 345 "terminator\n%.98s"), 346 nn->body); 347 corfile_puts(csound, "$error", csound->expanded_orc); 348 err = 1; break; 349 } 350 nn->body[i++] = c; 351 if (UNLIKELY(i >= size)) { 352 nn->body = csound->ReAlloc(csound, nn->body, 353 size += 100); 354 if (UNLIKELY(nn->body == NULL)) { 355 csound->Message(csound, Str("Memory exhausted")); 356 csound->LongJmp(csound, 1); 357 } 358 } 359 } 360 nn->body[i] = '\0'; 361 csound->Message(csound, "as...#%s#\n", nn->body); 362 nn->acnt = 0; /* No arguments for arguments */ 363 nn->next = csound->orc_macros; 364 csound->orc_macros = nn; 365 } 366 if (!err) { 367 //csound->DebugMsg(csound,"New body: ...#%s#\n", mm->body); 368 if (UNLIKELY(PARM->macro_stack_ptr +1 >= 369 PARM->macro_stack_size )) { 370 PARM->alt_stack = 371 (MACRON*) 372 csound->ReAlloc(csound, PARM->alt_stack, 373 sizeof(MACRON)* 374 (PARM->macro_stack_size+=S_INC)); 375 if (UNLIKELY(PARM->alt_stack == NULL)) { 376 csound->Message(csound, Str("Memory exhausted")); 377 csound->LongJmp(csound, 1); 378 } 379 /* csound->DebugMsg(csound, */ 380 /* "macro_stack extends alt_stack to %d long\n", */ 381 /* PARM->macro_stack_size); */ 382 } 383 PARM->alt_stack[PARM->macro_stack_ptr].n = 384 csound->orc_macros->acnt; 385 PARM->alt_stack[PARM->macro_stack_ptr].line = 386 csound_preget_lineno(yyscanner); 387 PARM->alt_stack[PARM->macro_stack_ptr].path = NULL; 388 PARM->alt_stack[PARM->macro_stack_ptr++].s = csound->orc_macros; 389 PARM->alt_stack[PARM->macro_stack_ptr].n = 0; 390 PARM->alt_stack[PARM->macro_stack_ptr].line = 391 csound_preget_lineno(yyscanner); 392 PARM->alt_stack[PARM->macro_stack_ptr].path = NULL; 393 /* printf("stacked line = %llu at %d\n", */ 394 /* csound_preget_lineno(yyscanner), */ 395 /* PARM->macro_stack_ptr-1); */ 396 PARM->alt_stack[PARM->macro_stack_ptr].s = NULL; 397 //csound->DebugMsg(csound,"Push %p macro stack\n", 398 // csound->orc_macros); 399 yypush_buffer_state(YY_CURRENT_BUFFER, yyscanner); 400 csound_preset_lineno(1, yyscanner); 401 if (UNLIKELY(PARM->depth>1022)) { 402 csound->Message(csound, 403 Str("macros/include nested too deep: ")); 404 corfile_puts(csound, "$error", csound->expanded_orc); 405 err = 1; 406 } 407 } 408 if (!err) { 409 PARM->lstack[++PARM->depth] = 410 (strchr(mm->body,'\n') ?file_to_int(csound, mname) : 63); 411 yy_scan_string(mm->body, yyscanner); 412 csound_preset_lineno(0, yyscanner); /* for Valgrind */ 413 } 414 } 415 } 416 {INCLUDESTR} { 417 if (PARM->isString != 1) 418 PARM->isinclude = 1; 419 else 420 corfile_puts(csound, yytext, csound->expanded_orc); 421 } 422 {INCLUDE} { 423 if (PARM->isString != 1) 424 BEGIN(incl); 425 else 426 corfile_puts(csound, yytext, csound->expanded_orc); 427 } 428 <incl>[ \t]* /* eat the whitespace */ 429 <incl>. { /* got the include file name */ 430 do_include(csound, yytext[0], yyscanner); 431 BEGIN(INITIAL); 432 } 433 #exit { corfile_putc(csound, '\0', csound->expanded_orc); 434 corfile_putc(csound, '\0', csound->expanded_orc); 435 //delete_macros(csound, yyscanner); 436 return 0;} 437 <<EOF>> { 438 MACRO *x, *y=NULL; 439 int n; 440 /* csound->DebugMsg(csound,"*********Leaving buffer %p\n", */ 441 /* YY_CURRENT_BUFFER); */ 442 yypop_buffer_state(yyscanner); 443 PARM->depth--; 444 if (UNLIKELY(PARM->depth > 1024)) 445 csound->Die(csound, Str("unexpected EOF!")); 446 PARM->llocn = PARM->locn; PARM->locn = make_location(PARM); 447 /* csound->DebugMsg(csound,"%s(%d): loc=%Ld; lastloc=%Ld\n", */ 448 /* __FILE__, __LINE__, */ 449 /* PARM->llocn, PARM->locn); */ 450 if ( !YY_CURRENT_BUFFER ) yyterminate(); 451 csound->DebugMsg(csound,"End of input; popping to %p\n", 452 YY_CURRENT_BUFFER); 453 csound_pre_line(csound, csound->expanded_orc, yyscanner); 454 n = PARM->alt_stack[--PARM->macro_stack_ptr].n; 455 if (PARM->alt_stack[PARM->macro_stack_ptr].path) { 456 //printf("restoring path from %s to %s\n", 457 // PARM->path, PARM->alt_stack[PARM->macro_stack_ptr].path); 458 free(PARM->path); 459 PARM->path = PARM->alt_stack[PARM->macro_stack_ptr].path; 460 } 461 /* printf("lineno on stack is %llu\n", */ 462 /* PARM->alt_stack[PARM->macro_stack_ptr].line); */ 463 csound->DebugMsg(csound,"n=%d\n", n); 464 if (n!=0) { 465 /* We need to delete n macros starting with y */ 466 y = PARM->alt_stack[PARM->macro_stack_ptr].s; 467 x = csound->orc_macros; 468 if (x==y) { 469 while (n>0) { 470 mfree(csound, y->name); x=y->next; 471 mfree(csound, y); y=x; n--; 472 } 473 csound->orc_macros = x; 474 } 475 else { 476 MACRO *nxt = y->next; 477 while (x->next != y) x = x->next; 478 while (n>0) { 479 nxt = y->next; 480 mfree(csound, y->name); mfree(csound, y); y=nxt; n--; 481 } 482 x->next = nxt; 483 } 484 y->next = x; 485 } 486 csound_preset_lineno(PARM->alt_stack[PARM->macro_stack_ptr].line, 487 yyscanner); 488 csound->DebugMsg(csound, "csound_pre(%d): line now %d at %d\n", 489 __LINE__, 490 csound_preget_lineno(yyscanner), 491 PARM->macro_stack_ptr); 492 csound->DebugMsg(csound, 493 "End of input segment: macro pop %p -> %p\n", 494 y, csound->orc_macros); 495 //csound_preset_lineno(PARM->alt_stack[PARM->macro_stack_ptr].line, 496 // yyscanner); 497 //print_csound_predata(csound,"Before pre_line", yyscanner); 498 csound_pre_line(csound, csound->orchstr, yyscanner); 499 //print_csound_predata(csound,"After pre_line", yyscanner); 500 } 501 {DEFINE} { 502 if (PARM->isString != 1) 503 BEGIN(macro); 504 else 505 corfile_puts(csound, yytext, csound->expanded_orc); 506 } 507 <macro>[ \t]* /* eat the whitespace */ 508 <macro>{MACROB} { 509 yytext[yyleng-1] = '\0'; 510 csound->DebugMsg(csound,"Define macro with args %s\n", 511 yytext); 512 /* print_csound_predata(csound, "Before do_macro_arg", 513 yyscanner); */ 514 do_umacroq(csound, yytext, yyscanner); 515 do_macro_arg(csound, yytext, yyscanner); 516 //print_csound_predata(csound,"After do_macro_arg", yyscanner); 517 BEGIN(INITIAL); 518 } 519 <macro>{MACRO} { 520 csound->DebugMsg(csound,"Define macro %s\n", yytext); 521 /* print_csound_predata(csound,"Before do_macro", yyscanner); */ 522 do_umacroq(csound, yytext, yyscanner); 523 do_macro(csound, yytext, yyscanner); 524 //print_csound_predata(csound,"After do_macro", yyscanner); 525 BEGIN(INITIAL); 526 } 527 <macro>. { csound->Message(csound, 528 Str("Unexpected character %c(%.2x) line %d\n"), 529 yytext[0], yytext[0], 530 csound_preget_lineno(yyscanner)); 531 csound->LongJmp(csound, 1); 532 } 533 {UNDEF} { 534 if (PARM->isString != 1) 535 BEGIN(umacro); 536 else 537 corfile_puts(csound, yytext, csound->expanded_orc); 538 } 539 <umacro>[ \t]* /* eat the whitespace */ 540 <umacro>{MACRO} { 541 csound->DebugMsg(csound,"Undefine macro %s\n", yytext); 542 do_umacro(csound, yytext, yyscanner); 543 BEGIN(INITIAL); 544 } 545 546 {IFDEF} { 547 if (PARM->isString != 1) { 548 PARM->isIfndef = (yytext[3] == 'n'); /* #ifdef or #ifndef */ 549 csound_preset_lineno(1+csound_preget_lineno(yyscanner), 550 yyscanner); 551 corfile_putc(csound, '\n', csound->expanded_orc); 552 csound_pre_line(csound, csound->expanded_orc, yyscanner); 553 BEGIN(ifdef); 554 } 555 else { 556 corfile_puts(csound, yytext, csound->expanded_orc); 557 } 558 } 559 <ifdef>[ \t]* /* eat the whitespace */ 560 <ifdef>{IDENT} { 561 do_ifdef(csound, yytext, yyscanner); 562 BEGIN(INITIAL); 563 } 564 {ELSE} { 565 if (PARM->isString != 1) { 566 if (PARM->ifdefStack == NULL) { 567 csound->Message(csound, Str("#else without #if\n")); 568 csound->LongJmp(csound, 1); 569 } 570 else if (PARM->ifdefStack->isElse) { 571 csound->Message(csound, Str("#else after #else\n")); 572 csound->LongJmp(csound, 1); 573 } 574 PARM->ifdefStack->isElse = 1; 575 csound_preset_lineno(1+csound_preget_lineno(yyscanner), 576 yyscanner); 577 corfile_putc(csound, '\n', csound->expanded_orc); 578 csound_pre_line(csound, csound->expanded_orc, yyscanner); 579 do_ifdef_skip_code(csound, yyscanner); 580 } 581 else { 582 corfile_puts(csound, yytext, csound->expanded_orc); 583 } 584 } 585 {END} { 586 if (PARM->isString != 1) { 587 IFDEFSTACK *pp = PARM->ifdefStack; 588 if (UNLIKELY(pp == NULL)) { 589 csound->Message(csound, Str("Unmatched #end\n")); 590 csound->LongJmp(csound, 1); 591 } 592 PARM->ifdefStack = pp->prv; 593 csound_preset_lineno(1+csound_preget_lineno(yyscanner), 594 yyscanner); 595 corfile_putc(csound, '\n', csound->expanded_orc); 596 csound_pre_line(csound, csound->expanded_orc, yyscanner); 597 mfree(csound, pp); 598 } 599 else { 600 corfile_puts(csound, yytext, csound->expanded_orc); 601 } 602 } 603 {IDENT} { corfile_puts(csound, yytext,csound->expanded_orc); } 604 {INT} { do_function(csound, yytext,csound->expanded_orc); } 605 {FRAC} { do_function(csound, yytext,csound->expanded_orc); } 606 {ROUND} { do_function(csound, yytext,csound->expanded_orc); } 607 {FLOOR} { do_function(csound, yytext,csound->expanded_orc); } 608 {CEIL} { do_function(csound, yytext,csound->expanded_orc); } 609 {RND} { do_function(csound, yytext,csound->expanded_orc); } 610 {BIRND} { do_function(csound, yytext,csound->expanded_orc); } 611 {ABS} { do_function(csound, yytext,csound->expanded_orc); } 612 {EXP} { do_function(csound, yytext,csound->expanded_orc); } 613 {LOG} { do_function(csound, yytext,csound->expanded_orc); } 614 {SQRT} { do_function(csound, yytext,csound->expanded_orc); } 615 {SIN} { do_function(csound, yytext,csound->expanded_orc); } 616 {COS} { do_function(csound, yytext,csound->expanded_orc); } 617 {TAN} { do_function(csound, yytext,csound->expanded_orc); } 618 {SININV} { do_function(csound, yytext,csound->expanded_orc); } 619 {COSINV} { do_function(csound, yytext,csound->expanded_orc); } 620 {TANINV} { do_function(csound, yytext,csound->expanded_orc); } 621 {LOG10} { do_function(csound, yytext,csound->expanded_orc); } 622 {LOG2} { do_function(csound, yytext,csound->expanded_orc); } 623 {SINH} { do_function(csound, yytext,csound->expanded_orc); } 624 {COSH} { do_function(csound, yytext,csound->expanded_orc); } 625 {TANH} { do_function(csound, yytext,csound->expanded_orc); } 626 {AMPDB} { do_function(csound, yytext,csound->expanded_orc); } 627 {AMPDBFS} { do_function(csound, yytext,csound->expanded_orc); } 628 {DBAMP} { do_function(csound, yytext,csound->expanded_orc); } 629 {DBFSAMP} { do_function(csound, yytext,csound->expanded_orc); } 630 {FTCPS} { do_function(csound, yytext,csound->expanded_orc); } 631 {FTLEN} { do_function(csound, yytext,csound->expanded_orc); } 632 {FTSR} { do_function(csound, yytext,csound->expanded_orc); } 633 {FTLPTIM} { do_function(csound, yytext,csound->expanded_orc); } 634 {FTCHNLS} { do_function(csound, yytext,csound->expanded_orc); } 635 {I} { do_function(csound, yytext,csound->expanded_orc); } 636 {K} { do_function(csound, yytext,csound->expanded_orc); } 637 {CPSOCT} { do_function(csound, yytext,csound->expanded_orc); } 638 {OCTPCH} { do_function(csound, yytext,csound->expanded_orc); } 639 {CPSPCH} { do_function(csound, yytext,csound->expanded_orc); } 640 {PCHOCT} { do_function(csound, yytext,csound->expanded_orc); } 641 {OCTCPS} { do_function(csound, yytext,csound->expanded_orc); } 642 {NSAMP} { do_function(csound, yytext,csound->expanded_orc); } 643 {POWOFTWO} { do_function(csound, yytext,csound->expanded_orc); } 644 {LOGBTWO} { do_function(csound, yytext,csound->expanded_orc); } 645 {A} { do_function(csound, yytext,csound->expanded_orc); } 646 {TB0} { do_function(csound, yytext,csound->expanded_orc); } 647 {TB1} { do_function(csound, yytext,csound->expanded_orc); } 648 {TB2} { do_function(csound, yytext,csound->expanded_orc); } 649 {TB3} { do_function(csound, yytext,csound->expanded_orc); } 650 {TB4} { do_function(csound, yytext,csound->expanded_orc); } 651 {TB5} { do_function(csound, yytext,csound->expanded_orc); } 652 {TB6} { do_function(csound, yytext,csound->expanded_orc); } 653 {TB7} { do_function(csound, yytext,csound->expanded_orc); } 654 {TB8} { do_function(csound, yytext,csound->expanded_orc); } 655 {TB9} { do_function(csound, yytext,csound->expanded_orc); } 656 {TB10} { do_function(csound, yytext,csound->expanded_orc); } 657 {TB11} { do_function(csound, yytext,csound->expanded_orc); } 658 {TB12} { do_function(csound, yytext,csound->expanded_orc); } 659 {TB13} { do_function(csound, yytext,csound->expanded_orc); } 660 {TB14} { do_function(csound, yytext,csound->expanded_orc); } 661 {TB15} { do_function(csound, yytext,csound->expanded_orc); } 662 {URD} { do_function(csound, yytext,csound->expanded_orc); } 663 {NOT} { do_function(csound, yytext,csound->expanded_orc); } 664 {CENT} { do_function(csound, yytext,csound->expanded_orc); } 665 {OCTAVE} { do_function(csound, yytext,csound->expanded_orc); } 666 {SEMITONE} { do_function(csound, yytext,csound->expanded_orc); } 667 {CPSMIDIN} { do_function(csound, yytext,csound->expanded_orc); } 668 {OCTMIDIN} { do_function(csound, yytext,csound->expanded_orc); } 669 {PCHMIDIN} { do_function(csound, yytext,csound->expanded_orc); } 670 {DB} { do_function(csound, yytext,csound->expanded_orc); } 671 {P} { do_function(csound, yytext,csound->expanded_orc); } 672 {QINF} { do_function(csound, yytext,csound->expanded_orc); } 673 {QNAN} { do_function(csound, yytext,csound->expanded_orc); } 674 675 . { corfile_putc(csound, yytext[0], csound->expanded_orc); } 676 677 %% 678 void comment(yyscan_t yyscanner) /* Skip until nextline */ 679 { 680 char c; 681 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; 682 while ((c = input(yyscanner)) != '\n' && c != '\r') { /* skip */ 683 if (UNLIKELY((int)c == EOF || c == '\0')) { 684 YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = 685 YY_BUFFER_EOF_PENDING; 686 return; 687 } 688 } 689 if (c == '\r' && (c = input(yyscanner)) != '\n') { 690 if (LIKELY((int)c != EOF && c != '\0')) 691 unput(c); 692 else 693 YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = 694 YY_BUFFER_EOF_PENDING; 695 } 696 csound_preset_lineno(1+csound_preget_lineno(yyscanner),yyscanner); 697 } 698 699 void do_comment(yyscan_t yyscanner) /* Skip until * and / chars */ 700 { 701 int c; 702 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; 703 TOP: 704 c = input(yyscanner); 705 switch (c) { 706 NL: 707 case '\n': 708 csound_preset_lineno(1+csound_preget_lineno(yyscanner),yyscanner); 709 goto TOP; 710 case '*': 711 AST: 712 c = input(yyscanner); 713 switch (c) { 714 case '*': 715 goto AST; 716 case '\n': 717 goto NL; 718 case '/': 719 return; 720 case EOF: 721 case '\0': 722 goto ERR; 723 default: 724 goto TOP; 725 } 726 case EOF: 727 ERR: 728 YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = 729 YY_BUFFER_EOF_PENDING; 730 return; 731 default: 732 goto TOP; 733 } 734 } 735 #ifndef WIN32 736 int isDir(char *path) { 737 struct stat statbuf; 738 if (stat(path, &statbuf) != 0) 739 return 0; 740 return S_ISDIR(statbuf.st_mode); 741 } 742 #else 743 int isDir(char *path) { return 0;} 744 #endif 745 746 void do_include(CSOUND *csound, int term, yyscan_t yyscanner) 747 { 748 char buffer[100]; 749 int p=0; 750 int c; 751 CORFIL *cf; 752 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; 753 while ((c=input(yyscanner))!=term) { 754 if (c=='\n' || c==EOF || c=='\0') { 755 csound->Warning(csound, Str("Ill formed #include ignored")); 756 return; 757 } 758 buffer[p] = c; 759 p++; 760 } 761 buffer[p] = '\0'; 762 //printf("****buffer >>%s<<\n", buffer); 763 while ((c=input(yyscanner))!='\n'); 764 if (UNLIKELY(PARM->depth++>=1024)) { 765 csound->Die(csound, Str("Includes nested too deeply")); 766 } 767 csound_preset_lineno(1+csound_preget_lineno(yyscanner), yyscanner); 768 csound->DebugMsg(csound,"line %d at end of #include line\n", 769 csound_preget_lineno(yyscanner)); 770 { 771 uint8_t n = file_to_int(csound, buffer); 772 char bb[128]; 773 PARM->lstack[PARM->depth] = n; 774 sprintf(bb, "#source %"PRIu64"\n", PARM->locn = make_location(PARM)); 775 PARM->llocn = PARM->locn; 776 corfile_puts(csound, bb, csound->expanded_orc); 777 } 778 csound->DebugMsg(csound,"reading included file \"%s\"\n", buffer); 779 if (UNLIKELY(isDir(buffer))) 780 csound->Warning(csound, Str("%s is a directory; not including"), buffer); 781 if (PARM->path && buffer[0]!= DIRSEP) { // if nested included directories 782 char tmp[1024]; 783 printf("using path %s\n", PARM->path); 784 strncpy(tmp, PARM->path, 1023); 785 strcat(tmp, "/"); 786 strncat(tmp, buffer, 1022-strlen(tmp)); 787 if ((cf = copy_to_corefile(csound, tmp, "INCDIR", 0))==NULL) 788 cf = copy_to_corefile(csound, buffer, "INCDIR", 0); 789 } 790 else cf = copy_to_corefile(csound, buffer, "INCDIR", 0); 791 if (UNLIKELY(cf == NULL)) 792 csound->Die(csound, 793 Str("Cannot open #include'd file %s\n"), buffer); 794 if (UNLIKELY(PARM->macro_stack_ptr +1 >= PARM->macro_stack_size )) { 795 PARM->alt_stack = 796 (MACRON*) csound->ReAlloc(csound, PARM->alt_stack, 797 sizeof(MACRON)*(PARM->macro_stack_size+=S_INC)); 798 if (UNLIKELY(PARM->alt_stack == NULL)) { 799 csound->Message(csound, Str("Memory exhausted")); 800 csound->LongJmp(csound, 1); 801 } 802 /* csound->DebugMsg(csound, "alt_stack now %d long,\n", */ 803 /* PARM->macro_stack_size); */ 804 } 805 csound->DebugMsg(csound,"cso_pre(%d): stacking line %d at %d\n", __LINE__, 806 csound_preget_lineno(yyscanner),PARM->macro_stack_ptr); 807 PARM->alt_stack[PARM->macro_stack_ptr].n = 0; 808 PARM->alt_stack[PARM->macro_stack_ptr].line = csound_preget_lineno(yyscanner); 809 if (strrchr(buffer,DIRSEP)) { 810 PARM->alt_stack[PARM->macro_stack_ptr].path = PARM->path; 811 printf("setting path from %s to ", PARM->path); 812 PARM->path = strdup(buffer); /* wasteful! */ 813 *(strrchr(PARM->path,DIRSEP)) = '\0'; 814 printf("%s\n",PARM->path); 815 } 816 else PARM->alt_stack[PARM->macro_stack_ptr].path = NULL; 817 PARM->alt_stack[PARM->macro_stack_ptr++].s = NULL; 818 csound_prepush_buffer_state(YY_CURRENT_BUFFER, yyscanner); 819 csound_pre_scan_string(cf->body, yyscanner); 820 corfile_rm(csound, &cf); 821 csound->DebugMsg(csound,"Set line number to 1\n"); 822 csound_preset_lineno(1, yyscanner); 823 } 824 825 void do_new_include(CSOUND *csound, yyscan_t yyscanner) 826 { 827 char buffer[128]; 828 CORFIL *cf = csound->expanded_orc; 829 int p = cf->p-2; 830 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; 831 832 //printf("*** in do_new_include\n"); 833 cf->body[p+1] = '\0'; 834 while (cf->body[p]!='"') p--; 835 //printf("*** name is >>%s<<\n", &cf->body[p]); 836 cf->body[p] = '\0'; 837 strncpy(buffer, &cf->body[p+1],127); buffer[127]='\0'; 838 cf->p = p; 839 //printf("****buffer >>%s<<\n", buffer); 840 while ((input(yyscanner))!='\n'); 841 if (UNLIKELY(PARM->depth++>=1024)) { 842 csound->Die(csound, Str("Includes nested too deeply")); 843 } 844 csound_preset_lineno(1+csound_preget_lineno(yyscanner), yyscanner); 845 csound->DebugMsg(csound,"line %d at end of #include line\n", 846 csound_preget_lineno(yyscanner)); 847 { 848 uint8_t n = file_to_int(csound, buffer); 849 char bb[128]; 850 PARM->lstack[PARM->depth] = n; 851 sprintf(bb, "#source %"PRIu64"\n", PARM->locn = make_location(PARM)); 852 PARM->llocn = PARM->locn; 853 corfile_puts(csound, bb, csound->expanded_orc); 854 } 855 csound->DebugMsg(csound,"reading included file \"%s\"\n", buffer); 856 if (UNLIKELY(isDir(buffer))) 857 csound->Warning(csound, Str("%s is a directory; not including"), buffer); 858 if (PARM->path && buffer[0]!=DIRSEP) { 859 char tmp[1024]; 860 strncpy(tmp, PARM->path, 1023); 861 strcat(tmp, "/"); 862 strncat(tmp, buffer, 1022-strlen(tmp)); 863 cf = copy_to_corefile(csound, tmp, "INCDIR", 0); 864 } 865 else cf = copy_to_corefile(csound, buffer, "INCDIR", 0); 866 if (UNLIKELY(cf == NULL)) 867 csound->Die(csound, 868 Str("Cannot open #include'd file %s\n"), buffer); 869 if (UNLIKELY(PARM->macro_stack_ptr +1 >= PARM->macro_stack_size )) { 870 PARM->alt_stack = 871 (MACRON*) csound->ReAlloc(csound, PARM->alt_stack, 872 sizeof(MACRON)*(PARM->macro_stack_size+=S_INC)); 873 if (UNLIKELY(PARM->alt_stack == NULL)) { 874 csound->Message(csound, Str("Memory exhausted")); 875 csound->LongJmp(csound, 1); 876 } 877 /* csound->DebugMsg(csound, "alt_stack now %d long,\n", */ 878 /* PARM->macro_stack_size); */ 879 } 880 csound->DebugMsg(csound,"cso_pre(%d): stacking line %d at %d\n", __LINE__, 881 csound_preget_lineno(yyscanner),PARM->macro_stack_ptr); 882 PARM->alt_stack[PARM->macro_stack_ptr].n = 0; 883 PARM->alt_stack[PARM->macro_stack_ptr].line = csound_preget_lineno(yyscanner); 884 if (strrchr(buffer,DIRSEP)) { 885 PARM->alt_stack[PARM->macro_stack_ptr].path = PARM->path; 886 PARM->path = strdup(buffer); /* wasteful! */ 887 *(strrchr(PARM->path,DIRSEP)) = '\0'; 888 } 889 else PARM->alt_stack[PARM->macro_stack_ptr].path = NULL; 890 PARM->alt_stack[PARM->macro_stack_ptr++].s = NULL; 891 csound_prepush_buffer_state(YY_CURRENT_BUFFER, yyscanner); 892 csound_pre_scan_string(cf->body, yyscanner); 893 corfile_rm(csound, &cf); 894 csound->DebugMsg(csound,"Set line number to 1\n"); 895 csound_preset_lineno(1, yyscanner); 896 } 897 898 static inline int isNameChar(int c, int pos) 899 { 900 c = (int) ((unsigned char) c); 901 return (isalpha(c) || (pos && (c == '_' || isdigit(c)))); 902 } 903 904 static void do_macro_arg(CSOUND *csound, char *name0, yyscan_t yyscanner) 905 { 906 MACRO *mm = (MACRO*) csound->Malloc(csound, sizeof(MACRO)); 907 int arg = 0, i, c; 908 int size = 100; 909 int mlen = 40; 910 char *q = name0; 911 char *mname = malloc(mlen); 912 913 if (UNLIKELY(mm == NULL)) { 914 csound->Message(csound, Str("Memory exhausted")); 915 csound->LongJmp(csound, 1); 916 } 917 mm->margs = MARGS; /* Initial size */ 918 mm->name = (char*)csound->Malloc(csound, strlen(name0) + 1); 919 if (UNLIKELY(mm->name == NULL)) { 920 csound->Message(csound, Str("Memory exhausted")); 921 csound->LongJmp(csound, 1); 922 } 923 strcpy(mm->name, name0); 924 do { 925 i = 0; 926 q = name0; 927 mname[i++] = '`'; 928 while ((c = *q++)) { 929 mname[i++] = c; 930 if (UNLIKELY(i==mlen)) 931 mname = (char *)realloc(mname, mlen+=40); 932 if (UNLIKELY(mname == NULL)) { 933 csound->Message(csound, Str("Memory exhausted")); 934 csound->LongJmp(csound, 1); 935 } 936 } 937 mname[i++] = '`'; 938 if (UNLIKELY(i==mlen)) { 939 mname = (char *)realloc(mname, mlen+=40); 940 if (UNLIKELY(mname == NULL)) { 941 csound->Message(csound, Str("Memory exhausted")); 942 csound->LongJmp(csound, 1); 943 } 944 } 945 mname[i++] = '`'; 946 if (UNLIKELY(i==mlen)) { 947 mname = (char *)realloc(mname, mlen+=40); 948 if (UNLIKELY(mname == NULL)) { 949 csound->Message(csound, Str("Memory exhausted")); 950 csound->LongJmp(csound, 1); 951 } 952 } 953 while (isspace((c = input(yyscanner)))); 954 955 while (isNameChar(c, i)) { 956 mname[i++] = c; 957 if (UNLIKELY(i==mlen)) { 958 mname = (char *)realloc(mname, mlen+=40); 959 if (UNLIKELY(mname == NULL)) { 960 csound->Message(csound, Str("Memory exhausted")); 961 csound->LongJmp(csound, 1); 962 } 963 } 964 c = input(yyscanner); 965 } 966 mname[i] = '\0'; 967 mm->arg[arg] = csound->Malloc(csound, i + 1); 968 if (UNLIKELY(mm->arg[arg] == NULL)) { 969 csound->Message(csound, Str("Memory exhausted")); 970 csound->LongJmp(csound, 1); 971 } 972 strcpy(mm->arg[arg++], mname); 973 if (UNLIKELY(arg >= mm->margs)) { 974 mm = (MACRO*) csound->ReAlloc(csound, mm, sizeof(MACRO) 975 + mm->margs * sizeof(char*)); 976 if (UNLIKELY(mm == NULL)) { 977 csound->Message(csound, Str("Memory exhausted")); 978 csound->LongJmp(csound, 1); 979 } 980 mm->margs += MARGS; 981 } 982 while (isspace(c)) 983 c = input(yyscanner); 984 } while (c == '\'' || c == '#'); 985 if (UNLIKELY(c != ')')) { 986 csound->Message(csound, Str("macro error\n")); 987 } 988 free(mname); 989 c = input(yyscanner); 990 while (c!='#') { 991 if (UNLIKELY(c==EOF || c=='\0')) 992 csound->Die(csound, Str("define macro runaway\n")); 993 else if (c==';') { 994 while ((c=input(yyscanner))!= '\n') 995 if (UNLIKELY(c==EOF || c=='\0')) { 996 csound->Die(csound, Str("define macro runaway\n")); 997 } 998 } 999 else if (c=='/') { 1000 if ((c=input(yyscanner))=='/') { 1001 while ((c=input(yyscanner))!= '\n') 1002 if (UNLIKELY(c==EOF || c=='\0')) 1003 csound->Die(csound, Str("define macro runaway\n")); 1004 } 1005 else if (c=='*') { 1006 while ((c=input(yyscanner))!='*') { 1007 again: 1008 if (UNLIKELY(c==EOF || c=='\0')) 1009 csound->Die(csound, Str("define macro runaway\n")); 1010 } 1011 if ((c=input(yyscanner))!='/') goto again; 1012 } 1013 } 1014 else if (UNLIKELY(!isspace(c))) 1015 csound->Die(csound, 1016 Str("define macro unexpected character %c(0x%.2x) awaiting #\n"), 1017 c, c); 1018 c = input(yyscanner); /* skip to start of body */ 1019 } 1020 mm->acnt = arg; 1021 i = 0; 1022 mm->body = (char*) csound->Malloc(csound, 100); 1023 if (UNLIKELY(mm->body == NULL)) { 1024 csound->Message(csound, Str("Memory exhausted")); 1025 csound->LongJmp(csound, 1); 1026 } 1027 1028 while ((c = input(yyscanner)) != '#') { /* read body */ 1029 if (UNLIKELY(c == EOF || c == '\0')) 1030 csound->Die(csound, Str("define macro with args: unexpected EOF")); 1031 if (c=='$') { /* munge macro name? */ 1032 int n = strlen(name0)+4; 1033 if (UNLIKELY(i+n >= size)) { 1034 mm->body = csound->ReAlloc(csound, mm->body, size += 100); 1035 if (UNLIKELY(mm->body == NULL)) { 1036 csound->Message(csound, Str("Memory exhausted")); 1037 csound->LongJmp(csound, 1); 1038 } 1039 } 1040 mm->body[i] = '$'; mm->body[i+1] = '`'; 1041 strcpy(&mm->body[i+2], name0); 1042 mm->body[i + n - 2] = '`'; mm->body[i + n - 1] = '`'; 1043 i+=n; 1044 continue; 1045 } 1046 mm->body[i++] = c=='\r'?'\n':c; 1047 if (UNLIKELY(i >= size)) { 1048 mm->body = csound->ReAlloc(csound, mm->body, size += 100); 1049 if (UNLIKELY(mm->body == NULL)) { 1050 csound->Message(csound, Str("Memory exhausted")); 1051 csound->LongJmp(csound, 1); 1052 } 1053 } 1054 if (c == '\\') { /* allow escaped # */ 1055 mm->body[i++] = c = input(yyscanner); 1056 if (UNLIKELY(i >= size)) { 1057 mm->body = csound->ReAlloc(csound, mm->body, size += 100); 1058 if (UNLIKELY(mm->body == NULL)) { 1059 csound->Message(csound, Str("Memory exhausted")); 1060 csound->LongJmp(csound, 1); 1061 } 1062 } 1063 } 1064 if (UNLIKELY(c == '\n' || c == '\r')) { 1065 csound_preset_lineno(1+csound_preget_lineno(yyscanner),yyscanner); 1066 corfile_putc(csound, '\n', csound->expanded_orc); 1067 csound_pre_line(csound, csound->expanded_orc, yyscanner); 1068 } 1069 } 1070 mm->body[i] = '\0'; 1071 mm->next = csound->orc_macros; 1072 csound->orc_macros = mm; 1073 } 1074 1075 static void do_macro(CSOUND *csound, char *name0, yyscan_t yyscanner) 1076 { 1077 MACRO *mm = (MACRO*) csound->Malloc(csound, sizeof(MACRO)); 1078 int i, c; 1079 int size = 100; 1080 if (UNLIKELY(mm == NULL)) { 1081 csound->Message(csound, Str("Memory exhausted")); 1082 csound->LongJmp(csound, 1); 1083 } 1084 1085 mm->margs = MARGS; /* Initial size */ 1086 csound->DebugMsg(csound,"Macro definition for %s\n", name0); 1087 mm->name = (char*)csound->Malloc(csound, strlen(name0) + 1); 1088 if (UNLIKELY(mm->name == NULL)) { 1089 csound->Message(csound, Str("Memory exhausted")); 1090 csound->LongJmp(csound, 1); 1091 } 1092 strcpy(mm->name, name0); 1093 mm->acnt = 0; 1094 i = 0; 1095 while ((c = input(yyscanner)) != '#') { 1096 if (UNLIKELY(c==EOF || c=='\0')) 1097 csound->Die(csound, Str("define macro runaway\n")); 1098 else if (c==';') { 1099 while ((c=input(yyscanner))!= '\n') 1100 if (UNLIKELY(c==EOF || c=='\0')) { 1101 csound->Die(csound, Str("define macro runaway\n")); 1102 } 1103 } 1104 else if (c=='/') { 1105 if ((c=input(yyscanner))=='/') { 1106 while ((c=input(yyscanner))!= '\n') 1107 if (UNLIKELY(c==EOF || c=='\0')) 1108 csound->Die(csound, Str("define macro runaway\n")); 1109 } 1110 else if (c=='*') { 1111 while ((c=input(yyscanner))!='*') { 1112 again: 1113 if (UNLIKELY(c==EOF || c=='\0')) 1114 csound->Die(csound, Str("define macro runaway\n")); 1115 } 1116 if ((c=input(yyscanner))!='/') goto again; 1117 } 1118 } 1119 else if (UNLIKELY(!isspace(c))) 1120 csound->Die(csound, 1121 Str("define macro unexpected character %c(0x%.2x)" 1122 " awaiting #\n"), 1123 c, c); 1124 } 1125 mm->body = (char*) csound->Malloc(csound, 100); 1126 if (UNLIKELY(mm->body == NULL)) { 1127 csound->Message(csound, Str("Memory exhausted")); 1128 csound->LongJmp(csound, 1); 1129 } 1130 while ((c = input(yyscanner)) != '#') { 1131 if (UNLIKELY(c == EOF || c=='\0')) 1132 csound->Die(csound, Str("define macro: unexpected EOF")); 1133 mm->body[i++] = c=='\r'?'\n':c; 1134 if (UNLIKELY(i >= size)) { 1135 mm->body = csound->ReAlloc(csound, mm->body, size += 100); 1136 if (UNLIKELY(mm->body == NULL)) { 1137 csound->Message(csound, Str("Memory exhausted")); 1138 csound->LongJmp(csound, 1); 1139 } 1140 } 1141 if (c == '\\') { /* allow escaped # */ 1142 mm->body[i++] = c = input(yyscanner); 1143 if (UNLIKELY(i >= size)) { 1144 mm->body = csound->ReAlloc(csound, mm->body, size += 100); 1145 if (UNLIKELY(mm->body == NULL)) { 1146 csound->Message(csound, Str("Memory exhausted")); 1147 csound->LongJmp(csound, 1); 1148 } 1149 } 1150 } 1151 if (UNLIKELY(c == '\n' || c == '\r')) { 1152 csound_preset_lineno(1+csound_preget_lineno(yyscanner),yyscanner); 1153 corfile_putc(csound, '\n', csound->expanded_orc); 1154 csound_pre_line(csound, csound->expanded_orc, yyscanner); 1155 } 1156 } 1157 mm->body[i] = '\0'; 1158 csound->DebugMsg(csound,"Body #%s#\n", mm->body); 1159 mm->next = csound->orc_macros; 1160 csound->orc_macros = mm; 1161 } 1162 1163 static void do_umacro(CSOUND *csound, char *name0, yyscan_t yyscanner) 1164 { 1165 int i,c; 1166 if (UNLIKELY(csound->oparms->msglevel)) 1167 csound->Message(csound,Str("macro %s undefined\n"), name0); 1168 csound->DebugMsg(csound, "macro %s undefined\n", name0); 1169 if (strcmp(name0, csound->orc_macros->name)==0) { 1170 MACRO *mm=csound->orc_macros->next; 1171 mfree(csound, csound->orc_macros->name); mfree(csound, csound->orc_macros->body); 1172 for (i=0; i<csound->orc_macros->acnt; i++) 1173 mfree(csound, csound->orc_macros->arg[i]); 1174 mfree(csound, csound->orc_macros); csound->orc_macros = mm; 1175 } 1176 else { 1177 MACRO *mm = csound->orc_macros; 1178 MACRO *nn = mm->next; 1179 while (strcmp(name0, nn->name) != 0) { 1180 mm = nn; nn = nn->next; 1181 if (UNLIKELY(nn == NULL)) { 1182 csound->Message(csound, Str("Undefining undefined macro")); 1183 csound->LongJmp(csound, 1); 1184 } 1185 } 1186 mfree(csound, nn->name); mfree(csound, nn->body); 1187 for (i=0; i<nn->acnt; i++) 1188 mfree(csound, nn->arg[i]); 1189 mm->next = nn->next; mfree(csound, nn); 1190 } 1191 while ((c=input(yyscanner)) != '\n' && 1192 c != EOF && c != '\r'); /* ignore rest of line */ 1193 csound_preset_lineno(1+csound_preget_lineno(yyscanner),yyscanner); 1194 } 1195 1196 static void do_umacroq(CSOUND *csound, char *name0, yyscan_t yyscanner) 1197 { 1198 int i; 1199 MACRO *mm = csound->orc_macros, *last = NULL; 1200 while (mm) { 1201 if (strcmp(name0, mm->name)==0) { 1202 MACRO *nn=mm->next; 1203 mfree(csound, mm->name); mfree(csound, mm->body); 1204 for (i=0; i<mm->acnt; i++) 1205 mfree(csound, mm->arg[i]); 1206 mfree(csound, mm); 1207 if (last) last->next = nn; 1208 else csound->orc_macros = nn; 1209 return; 1210 } 1211 last = mm; mm = last->next; 1212 } 1213 return; 1214 } 1215 1216 static void do_ifdef(CSOUND *csound, char *name0, yyscan_t yyscanner) 1217 { 1218 int c; 1219 MACRO *mm; 1220 IFDEFSTACK *pp; 1221 pp = (IFDEFSTACK*) csound->Calloc(csound, sizeof(IFDEFSTACK)); 1222 if (UNLIKELY(pp == NULL)) { 1223 csound->Message(csound, Str("Memory exhausted")); 1224 csound->LongJmp(csound, 1); 1225 } 1226 pp->prv = PARM->ifdefStack; 1227 pp->isDef = PARM->isIfndef; 1228 for (mm = csound->orc_macros; mm != NULL; mm = mm->next) { 1229 if (strcmp(name0, mm->name) == 0) { 1230 pp->isDef ^= (unsigned char) 1; 1231 break; 1232 } 1233 } 1234 PARM->ifdefStack = pp; 1235 pp->isSkip = pp->isDef ^ (unsigned char) 1; 1236 if (pp->isSkip) 1237 do_ifdef_skip_code(csound, yyscanner); 1238 else 1239 while ((c = input(yyscanner)) != '\n' && c != '\r' && c != EOF); 1240 } 1241 1242 static void do_ifdef_skip_code(CSOUND *csound, yyscan_t yyscanner) 1243 { 1244 int i, c, nested_ifdef = 0; 1245 char buf[8]; 1246 IFDEFSTACK *pp; 1247 /* buf = (char*)malloc(8*sizeof(char)); */ 1248 /* if (UNLIKELY(buf == NULL)) { */ 1249 /* csound->Message(csound, Str("Memory exhausted")); */ 1250 /* csound->LongJmp(csound, 1); */ 1251 /* } */ 1252 pp = PARM->ifdefStack; 1253 c = input(yyscanner); 1254 for (;;) { 1255 while (c!='\n' && c!= '\r') { 1256 if (UNLIKELY(c == EOF || c=='\0')) { 1257 csound->Message(csound, Str("Unmatched #if%sdef\n"), 1258 PARM->isIfndef ? "n" : ""); 1259 csound->LongJmp(csound, 1); 1260 } 1261 c = input(yyscanner); 1262 } 1263 csound_preset_lineno(1+csound_preget_lineno(yyscanner), 1264 yyscanner); 1265 corfile_putc(csound, '\n', csound->expanded_orc); 1266 csound_pre_line(csound, csound->expanded_orc, yyscanner); 1267 while (isblank(c = input(yyscanner))); /* eat the whitespace */ 1268 if (c == '#') { 1269 for (i=0; islower(c = input(yyscanner)) && i < 7; i++) 1270 buf[i] = c; 1271 buf[i] = '\0'; 1272 if (strcmp("end", buf) == 0 || strcmp("endif", buf) == 0) { 1273 if (nested_ifdef-- == 0) { 1274 PARM->ifdefStack = pp->prv; 1275 mfree(csound, pp); 1276 break; 1277 } 1278 } 1279 else if (strcmp("ifdef", buf) == 0 || strcmp("ifndef", buf) == 0) { 1280 nested_ifdef++; 1281 } 1282 else if (strcmp("else", buf) == 0 && nested_ifdef == 0) { 1283 if (UNLIKELY(pp->isElse)) { 1284 csound->Message(csound, Str("#else after #else\n")); 1285 csound->LongJmp(csound, 1); 1286 } 1287 pp->isElse = 1; 1288 break; 1289 } 1290 } 1291 } 1292 while (c != '\n' && c != EOF && c != '\r') c = input(yyscanner); 1293 } 1294 1295 #if 0 1296 static void delete_macros(CSOUND *csound, yyscan_t yyscanner) 1297 { 1298 MACRO * qq = csound->orc_macros; 1299 if (qq) { 1300 MACRO *mm = qq; 1301 while (mm) { 1302 csound->Free(csound, mm->body); 1303 csound->Free(csound, mm->name); 1304 qq = mm->next; 1305 csound->Free(csound, mm); 1306 mm = qq; 1307 } 1308 } 1309 } 1310 #endif 1311 1312 static void add_math_const_macro(CSOUND *csound, char * name, char *body) 1313 { 1314 MACRO *mm; 1315 1316 mm = (MACRO*) csound->Calloc(csound, sizeof(MACRO)); 1317 mm->name = (char*) csound->Calloc(csound, strlen(name) + 3); 1318 sprintf(mm->name, "M_%s", name); 1319 mm->next = csound->orc_macros; 1320 csound->orc_macros = mm; 1321 mm->margs = MARGS; /* Initial size */ 1322 mm->acnt = 0; 1323 mm->body = (char*) csound->Calloc(csound, strlen(body) + 1); 1324 mm->body = strcpy(mm->body, body); 1325 } 1326 1327 /** 1328 * Add math constants from math.h as orc csound->orc_macros 1329 */ 1330 void cs_init_math_constants_macros(CSOUND *csound) 1331 { 1332 if (csound->orc_macros == NULL) { 1333 add_math_const_macro(csound, "E", "2.71828182845904523536"); 1334 add_math_const_macro(csound, "LOG2E", "1.44269504088896340736"); 1335 add_math_const_macro(csound, "LOG10E","0.43429448190325182765"); 1336 add_math_const_macro(csound, "LN2", "0.69314718055994530942"); 1337 add_math_const_macro(csound, "LN10", "2.30258509299404568402"); 1338 add_math_const_macro(csound, "PI", "3.14159265358979323846"); 1339 add_math_const_macro(csound, "PI_2", "1.57079632679489661923"); 1340 add_math_const_macro(csound, "PI_4", "0.78539816339744830962"); 1341 add_math_const_macro(csound, "1_PI", "0.31830988618379067154"); 1342 add_math_const_macro(csound, "2_PI", "0.63661977236758134308"); 1343 add_math_const_macro(csound, "2_SQRTPI", "1.12837916709551257390"); 1344 add_math_const_macro(csound, "SQRT2", "1.41421356237309504880"); 1345 add_math_const_macro(csound, "SQRT1_2","0.70710678118654752440"); 1346 add_math_const_macro(csound, "INF", "800000000000.0");/* ~25367 years */ 1347 } 1348 } 1349 1350 void cs_init_omacros(CSOUND *csound, NAMES *nn) 1351 { 1352 while (nn) { 1353 char *s = nn->mac; 1354 char *p = strchr(s, '='); 1355 char *mname; 1356 MACRO *mm; 1357 1358 if (p == NULL) 1359 p = s + strlen(s); 1360 if (csound->oparms->msglevel & 7) 1361 csound->Message(csound, Str("Macro definition for %*s\n"), (int)(p - s), s); 1362 s = strchr(s, ':') + 1; /* skip arg bit */ 1363 if (UNLIKELY(s == NULL || s >= p)) { 1364 csound->Die(csound, Str("Invalid macro name for --omacro")); 1365 } 1366 mname = (char*) csound->Malloc(csound, (p - s) + 1); 1367 if (UNLIKELY(mname == NULL)) { 1368 csound->Message(csound, Str("Memory exhausted")); 1369 csound->LongJmp(csound, 1); 1370 } 1371 strncpy(mname, s, p - s); 1372 mname[p - s] = '\0'; 1373 /* check if macro is already defined */ 1374 for (mm = csound->orc_macros; mm != NULL; mm = mm->next) { 1375 if (strcmp(mm->name, mname) == 0) 1376 break; 1377 } 1378 if (mm == NULL) { 1379 mm = (MACRO*) csound->Calloc(csound, sizeof(MACRO)); 1380 if (UNLIKELY(mm == NULL)) { 1381 csound->Message(csound, Str("Memory exhausted")); 1382 csound->LongJmp(csound, 1); 1383 } 1384 mm->name = mname; 1385 mm->next = csound->orc_macros; 1386 csound->orc_macros = mm; 1387 } 1388 else 1389 mfree(csound, mname); 1390 mm->margs = MARGS; /* Initial size */ 1391 mm->acnt = 0; 1392 if (*p != '\0') 1393 p++; 1394 mm->body = (char*) csound->Malloc(csound, strlen(p) + 1); 1395 if (UNLIKELY(mm->body == NULL)) { 1396 csound->Message(csound, Str("Memory exhausted")); 1397 csound->LongJmp(csound, 1); 1398 } 1399 strcpy(mm->body, p); 1400 nn = nn->next; 1401 } 1402 } 1403 1404 /* int csound_prewrap(void *yyscanner) */ 1405 /* { */ 1406 /* return 1; */ 1407 /* } */ 1408 1409 void csound_pre_line(CSOUND *csound, CORFIL* cf, void *yyscanner) 1410 { 1411 int n = csound_preget_lineno(yyscanner); 1412 //printf("line number %d\n", n); 1413 /* This assumes that the initial line was not written with this system */ 1414 if (cf->p>0 && cf->body[cf->p-1]=='\n') { 1415 uint64_t locn = PARM->locn; 1416 uint64_t llocn = PARM->llocn; 1417 if (UNLIKELY(locn != llocn)) { 1418 char bb[80]; 1419 sprintf(bb, "#source %"PRIu64"\n", locn); 1420 corfile_puts(csound, bb, cf); 1421 } 1422 PARM->llocn = locn; 1423 if (UNLIKELY(n!=PARM->line+1)) { 1424 char bb[80]; 1425 sprintf(bb, "#line %d\n", n); 1426 corfile_puts(csound, bb, cf); 1427 } 1428 } 1429 PARM->line = n; 1430 } 1431 1432 void do_function(CSOUND *csound, char *text, CORFIL *cf) 1433 { 1434 char *p = text; 1435 //printf("do_function on >>%s<<\n", text); 1436 while (*p != '\0') { 1437 if (!isspace(*p)) corfile_putc(csound, *p, cf); 1438 p++; 1439 } 1440 return; 1441 } 1442 1443 static MACRO *find_definition(MACRO *mmo, char *s) 1444 { 1445 MACRO *mm = mmo; 1446 if (s[strlen(s)-1]=='.') s[strlen(s)-1]='\0'; 1447 else if (s[strlen(s)-2]=='.' && s[strlen(s)-1]=='(') { 1448 s[strlen(s)-2] = '('; s[strlen(s)-1] = '\0'; } 1449 // printf("****Looking for %s strlen=%d\n", s, strlen(s), s[strlen(s)-1]); 1450 while (mm != NULL) { /* Find the definition */ 1451 //printf("looking at %p(%s) body #%s#\n", mm, mm->name, mm->body); 1452 if (!(strcmp(s, mm->name))) break; 1453 mm = mm->next; 1454 } 1455 if (mm == NULL) { 1456 mm = mmo; 1457 s++; /* skip _ */ 1458 looking: 1459 while (*s++!='`') { if (*s=='\0') return NULL; } 1460 if (*s++!='`') { s--; goto looking; } 1461 //printf("now try looking for %s\n", s); 1462 while (mm != NULL) { /* Find the definition */ 1463 //printf("looking at %p(%s) body #%s#\n", mm, mm->name, mm->body); 1464 if (!(strcmp(s, mm->name))) break; 1465 mm = mm->next; 1466 } 1467 } 1468 //if (mm) printf("found body #%s#\n****\n", mm->body); 1469 return mm; 1470 } 1471 1472 1473 #if 0 1474 static void print_csound_predata(CSOUND *csound, char *mesg, void *yyscanner) 1475 { 1476 struct yyguts_t *yyg =(struct yyguts_t*)yyscanner; 1477 csound->DebugMsg(csound,"********* %s extra data ************", mesg); 1478 csound->DebugMsg(csound,"yyscanner = %p", yyscanner); 1479 csound->DebugMsg(csound,"yyextra_r = %p, yyin_r = %p, yyout_r = %p," 1480 " yy_buffer_stack_top = %d", 1481 yyg->yyextra_r, yyg->yyin_r,yyg->yyout_r, yyg->yy_buffer_stack_top); 1482 csound->DebugMsg(csound,"yy_buffer_stack_max = %d1, yy_buffer_stack = %p, " 1483 "yy_hold_char = %d '%c'", 1484 yyg->yy_buffer_stack_max, yyg->yy_buffer_stack, yyg->yy_hold_char, 1485 yyg->yy_hold_char); 1486 csound->DebugMsg(csound,"yy_n_chars = %d, yyleng_r = %d, yy_c_buf_p = %p %c", 1487 yyg->yy_n_chars, yyg->yyleng_r, yyg->yy_c_buf_p, *yyg->yy_c_buf_p); 1488 csound->DebugMsg(csound,"yy_init = %d, yy_start = %d, " 1489 "yy_did_buffer_switch_on_eof = %d", 1490 yyg->yy_init, yyg->yy_start, yyg->yy_did_buffer_switch_on_eof); 1491 csound->DebugMsg(csound,"yy_start_stack_ptr = %d," 1492 " yy_start_stack_depth = %d, yy_start_stack = %p", 1493 yyg->yy_start_stack_ptr, yyg->yy_start_stack_depth, yyg->yy_start_stack); 1494 1495 csound->DebugMsg(csound,"yy_last_accepting_state = %d, " 1496 "yy_last_accepting_cpos = %p %c", 1497 yyg->yy_last_accepting_state, yyg->yy_last_accepting_cpos, 1498 *yyg->yy_last_accepting_cpos); 1499 csound->DebugMsg(csound,"yylineno_r = %d, yy_flex_debug_r = %d, " 1500 "yytext_r = %p \"%s\", yy_more_flag = %d, yy_more_len = %d", 1501 yyg->yylineno_r, yyg->yy_flex_debug_r, yyg->yytext_r, yyg->yytext_r, 1502 yyg->yy_more_flag, yyg->yy_more_len); 1503 { 1504 PRE_PARM* pp = yyg->yyextra_r; 1505 printf("macros = %p, isIfndef = %d, isString = %d, line - %d loc = %d\n", 1506 pp->macros, pp->isIfndef, pp->isString, pp->line, pp->locn); 1507 printf 1508 ("llocn = %d dept=%d\n", pp->llocn, pp->depth); 1509 } 1510 csound->DebugMsg(csound,"*********\n"); 1511 } 1512 #endif 1513