[444] | 1 | /* chew |
---|
| 2 | Copyright (C) 1990-1992 Free Software Foundation, Inc. |
---|
| 3 | Contributed by steve chamberlain @cygnus |
---|
| 4 | |
---|
| 5 | |
---|
| 6 | This program is free software; you can redistribute it and/or modify |
---|
| 7 | it under the terms of the GNU General Public License as published by |
---|
| 8 | the Free Software Foundation; either version 2 of the License, or |
---|
| 9 | (at your option) any later version. |
---|
| 10 | |
---|
| 11 | This program is distributed in the hope that it will be useful, |
---|
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
| 14 | GNU General Public License for more details. |
---|
| 15 | |
---|
| 16 | You should have received a copy of the GNU General Public License |
---|
| 17 | along with this program; if not, write to the Free Software |
---|
| 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ |
---|
| 19 | |
---|
| 20 | /* |
---|
| 21 | Yet another way of extracting documentation from source. |
---|
| 22 | No, I haven't finished it yet, but I hope you people like it better |
---|
| 23 | that the old way |
---|
| 24 | |
---|
| 25 | sac |
---|
| 26 | |
---|
| 27 | Basically, this is a sort of string forth, maybe we should call it |
---|
| 28 | struth? |
---|
| 29 | |
---|
| 30 | You define new words thus: |
---|
| 31 | : <newword> <oldwords> ; |
---|
| 32 | There is no |
---|
| 33 | |
---|
| 34 | */ |
---|
| 35 | |
---|
| 36 | |
---|
| 37 | |
---|
| 38 | #include <stdio.h> |
---|
| 39 | #include <stdlib.h> |
---|
| 40 | #include <ctype.h> |
---|
| 41 | #include <string.h> |
---|
| 42 | #include <stdint.h> |
---|
| 43 | |
---|
| 44 | #define DEF_SIZE 5000 |
---|
| 45 | #define STACK 50 |
---|
| 46 | #define MIN_CMDLEN 4 /* Minimum length of a command */ |
---|
| 47 | |
---|
| 48 | int internal_wanted; |
---|
| 49 | int internal_mode; |
---|
| 50 | int Verbose=0; |
---|
| 51 | |
---|
| 52 | |
---|
| 53 | |
---|
| 54 | /* Here is a string type ... */ |
---|
| 55 | |
---|
| 56 | typedef struct buffer |
---|
| 57 | { |
---|
| 58 | char *ptr; |
---|
| 59 | unsigned int write_idx; |
---|
| 60 | unsigned int size; |
---|
| 61 | } string_type; |
---|
| 62 | |
---|
| 63 | |
---|
| 64 | |
---|
| 65 | |
---|
| 66 | |
---|
| 67 | |
---|
| 68 | |
---|
| 69 | static void |
---|
| 70 | init_string_with_size (string_type *buffer, unsigned int size) |
---|
| 71 | { |
---|
| 72 | buffer->write_idx = 0; |
---|
| 73 | buffer->size = size; |
---|
| 74 | buffer->ptr = malloc(size); |
---|
| 75 | } |
---|
| 76 | |
---|
| 77 | static void |
---|
| 78 | init_string (string_type *buffer) |
---|
| 79 | { |
---|
| 80 | init_string_with_size(buffer, DEF_SIZE); |
---|
| 81 | |
---|
| 82 | } |
---|
| 83 | |
---|
| 84 | static int |
---|
| 85 | find (string_type *str, char *what) |
---|
| 86 | { |
---|
| 87 | unsigned int i; |
---|
| 88 | char *p; |
---|
| 89 | p = what; |
---|
| 90 | for (i = 0; i < str->write_idx && *p; i++) |
---|
| 91 | { |
---|
| 92 | if (*p == str->ptr[i]) |
---|
| 93 | p++; |
---|
| 94 | else |
---|
| 95 | p = what; |
---|
| 96 | } |
---|
| 97 | return (*p == 0); |
---|
| 98 | |
---|
| 99 | } |
---|
| 100 | |
---|
| 101 | static void |
---|
| 102 | write_buffer (string_type *buffer) |
---|
| 103 | { |
---|
| 104 | fwrite(buffer->ptr, buffer->write_idx, 1, stdout); |
---|
| 105 | } |
---|
| 106 | |
---|
| 107 | |
---|
| 108 | static void |
---|
| 109 | delete_string (string_type *buffer) |
---|
| 110 | { |
---|
| 111 | free(buffer->ptr); |
---|
| 112 | } |
---|
| 113 | |
---|
| 114 | |
---|
| 115 | static char * |
---|
| 116 | addr (string_type *buffer, unsigned int idx) |
---|
| 117 | { |
---|
| 118 | return buffer->ptr + idx; |
---|
| 119 | } |
---|
| 120 | |
---|
| 121 | static char |
---|
| 122 | at (string_type *buffer, unsigned int pos) |
---|
| 123 | { |
---|
| 124 | if ( pos >= buffer->write_idx) |
---|
| 125 | { |
---|
| 126 | return 0; |
---|
| 127 | } |
---|
| 128 | return buffer->ptr[pos]; |
---|
| 129 | } |
---|
| 130 | |
---|
| 131 | static void |
---|
| 132 | catchar (string_type *buffer, char ch) |
---|
| 133 | { |
---|
| 134 | if (buffer->write_idx == buffer->size) |
---|
| 135 | { |
---|
| 136 | buffer->size *=2; |
---|
| 137 | buffer->ptr = realloc(buffer->ptr, buffer->size); |
---|
| 138 | } |
---|
| 139 | |
---|
| 140 | buffer->ptr[buffer->write_idx ++ ] = ch; |
---|
| 141 | } |
---|
| 142 | |
---|
| 143 | |
---|
| 144 | static void |
---|
| 145 | overwrite_string (string_type *dst, string_type *src) |
---|
| 146 | { |
---|
| 147 | free(dst->ptr); |
---|
| 148 | dst->size = src->size; |
---|
| 149 | dst->write_idx = src->write_idx; |
---|
| 150 | dst->ptr = src->ptr; |
---|
| 151 | } |
---|
| 152 | |
---|
| 153 | static void |
---|
| 154 | catstr (string_type *dst, string_type *src) |
---|
| 155 | { |
---|
| 156 | unsigned int i; |
---|
| 157 | for (i = 0; i < src->write_idx; i++) |
---|
| 158 | { |
---|
| 159 | catchar(dst, src->ptr[i]); |
---|
| 160 | } |
---|
| 161 | } |
---|
| 162 | |
---|
| 163 | |
---|
| 164 | static void |
---|
| 165 | cattext (string_type *buffer, char *string) |
---|
| 166 | { |
---|
| 167 | |
---|
| 168 | while (*string) |
---|
| 169 | { |
---|
| 170 | catchar(buffer, *string); |
---|
| 171 | string++; |
---|
| 172 | } |
---|
| 173 | } |
---|
| 174 | |
---|
| 175 | static void |
---|
| 176 | catbuf (string_type *buffer, char *buf, unsigned int len) |
---|
| 177 | { |
---|
| 178 | |
---|
| 179 | while (len--) |
---|
| 180 | { |
---|
| 181 | catchar(buffer, *buf); |
---|
| 182 | buf++; |
---|
| 183 | } |
---|
| 184 | } |
---|
| 185 | |
---|
| 186 | |
---|
| 187 | |
---|
| 188 | static unsigned int |
---|
| 189 | skip_white_and_stars (string_type *src, unsigned int idx) |
---|
| 190 | { |
---|
| 191 | while (isspace(at(src,idx)) |
---|
| 192 | || (at(src,idx) == '*' && at(src,idx +1) !='/')) |
---|
| 193 | idx++; |
---|
| 194 | return idx; |
---|
| 195 | |
---|
| 196 | |
---|
| 197 | } |
---|
| 198 | /***********************************************************************/ |
---|
| 199 | |
---|
| 200 | |
---|
| 201 | string_type stack[STACK]; |
---|
| 202 | string_type *tos; |
---|
| 203 | |
---|
| 204 | unsigned int idx = 0; /* Pos in input buffer */ |
---|
| 205 | string_type *ptr; /* and the buffer */ |
---|
| 206 | typedef void (*stinst_type)(void); |
---|
| 207 | stinst_type *pc; |
---|
| 208 | stinst_type sstack[STACK]; |
---|
| 209 | stinst_type *ssp = &sstack[0]; |
---|
| 210 | uintptr_t istack[STACK]; |
---|
| 211 | uintptr_t *isp = &istack[0]; |
---|
| 212 | |
---|
| 213 | typedef uintptr_t *word_type; |
---|
| 214 | |
---|
| 215 | |
---|
| 216 | |
---|
| 217 | struct dict_struct |
---|
| 218 | { |
---|
| 219 | char *word; |
---|
| 220 | struct dict_struct *next; |
---|
| 221 | stinst_type *code; |
---|
| 222 | int code_length; |
---|
| 223 | int code_end; |
---|
| 224 | int var; |
---|
| 225 | |
---|
| 226 | }; |
---|
| 227 | typedef struct dict_struct dict_type; |
---|
| 228 | #define WORD(x) static void x(void) |
---|
| 229 | |
---|
| 230 | static void |
---|
| 231 | exec (dict_type *word) |
---|
| 232 | { |
---|
| 233 | pc = word->code; |
---|
| 234 | while (*pc) |
---|
| 235 | { |
---|
| 236 | (*pc)(); |
---|
| 237 | } |
---|
| 238 | |
---|
| 239 | } |
---|
| 240 | WORD(call) |
---|
| 241 | { |
---|
| 242 | stinst_type *oldpc = pc; |
---|
| 243 | dict_type *e; |
---|
| 244 | e = (dict_type *)(pc [1]); |
---|
| 245 | exec(e); |
---|
| 246 | pc = oldpc + 2; |
---|
| 247 | |
---|
| 248 | } |
---|
| 249 | |
---|
| 250 | WORD(remchar) |
---|
| 251 | { |
---|
| 252 | tos->write_idx--; |
---|
| 253 | pc++; |
---|
| 254 | |
---|
| 255 | } |
---|
| 256 | |
---|
| 257 | WORD(push_number) |
---|
| 258 | { |
---|
| 259 | isp++; |
---|
| 260 | pc++; |
---|
| 261 | *isp = (uintptr_t)(*pc); |
---|
| 262 | pc++; |
---|
| 263 | |
---|
| 264 | } |
---|
| 265 | |
---|
| 266 | |
---|
| 267 | |
---|
| 268 | |
---|
| 269 | WORD(push_text) |
---|
| 270 | { |
---|
| 271 | |
---|
| 272 | tos++; |
---|
| 273 | init_string(tos); |
---|
| 274 | pc++; |
---|
| 275 | cattext(tos,*((char **)pc)); |
---|
| 276 | pc++; |
---|
| 277 | |
---|
| 278 | } |
---|
| 279 | |
---|
| 280 | |
---|
| 281 | |
---|
| 282 | /* This function removes everything not inside comments starting on |
---|
| 283 | the first char of the line from the string, also when copying |
---|
| 284 | comments, removes blank space and leading *'s |
---|
| 285 | Blank lines are turned into one blank line |
---|
| 286 | */ |
---|
| 287 | |
---|
| 288 | static void |
---|
| 289 | remove_noncomments (string_type *src, string_type *dst) |
---|
| 290 | { |
---|
| 291 | unsigned int idx = 0; |
---|
| 292 | |
---|
| 293 | while (at(src,idx)) |
---|
| 294 | { |
---|
| 295 | /* Now see if we have a comment at the start of the line */ |
---|
| 296 | if (at(src,idx) == '\n' |
---|
| 297 | && at(src,idx+1) == '/' |
---|
| 298 | && at(src,idx+2) == '*') |
---|
| 299 | { |
---|
| 300 | idx+=3; |
---|
| 301 | |
---|
| 302 | idx = skip_white_and_stars(src,idx); |
---|
| 303 | |
---|
| 304 | /* Remove leading dot */ |
---|
| 305 | if (at(src, idx) == '.') |
---|
| 306 | idx++; |
---|
| 307 | |
---|
| 308 | /* Copy to the end of the line, or till the end of the |
---|
| 309 | comment */ |
---|
| 310 | while (at(src, idx)) |
---|
| 311 | { |
---|
| 312 | if (at(src, idx) == '\n') |
---|
| 313 | { |
---|
| 314 | /* end of line, echo and scrape of leading blanks */ |
---|
| 315 | if (at(src,idx +1) == '\n') |
---|
| 316 | catchar(dst,'\n'); |
---|
| 317 | catchar(dst,'\n'); |
---|
| 318 | idx++; |
---|
| 319 | idx = skip_white_and_stars(src, idx); |
---|
| 320 | } |
---|
| 321 | else if (at(src, idx) == '*' && at(src,idx+1) == '/') |
---|
| 322 | { |
---|
| 323 | idx +=2 ; |
---|
| 324 | cattext(dst,"\nENDDD\n"); |
---|
| 325 | break; |
---|
| 326 | } |
---|
| 327 | else |
---|
| 328 | { |
---|
| 329 | catchar(dst, at(src, idx)); |
---|
| 330 | idx++; |
---|
| 331 | } |
---|
| 332 | } |
---|
| 333 | } |
---|
| 334 | else idx++; |
---|
| 335 | } |
---|
| 336 | } |
---|
| 337 | /* turn foobar name(stuff); into foobar EXFUN(name,(stuff)); |
---|
| 338 | |
---|
| 339 | */ |
---|
| 340 | |
---|
| 341 | static void |
---|
| 342 | exfunstuff (void) |
---|
| 343 | { |
---|
| 344 | unsigned int openp; |
---|
| 345 | unsigned int fname; |
---|
| 346 | unsigned int idx; |
---|
| 347 | string_type out; |
---|
| 348 | init_string(&out); |
---|
| 349 | |
---|
| 350 | |
---|
| 351 | /* make sure that it's not already exfuned */ |
---|
| 352 | if(find(tos,"EXFUN") || find(tos,"PROTO") || !find(tos,"(")) { |
---|
| 353 | catstr(&out,tos); |
---|
| 354 | } |
---|
| 355 | else |
---|
| 356 | { |
---|
| 357 | |
---|
| 358 | /*Find the open paren*/ |
---|
| 359 | for (openp = 0; at(tos, openp) != '(' && at(tos,openp); openp++) |
---|
| 360 | ; |
---|
| 361 | |
---|
| 362 | fname = openp; |
---|
| 363 | /* Step back to the fname */ |
---|
| 364 | fname--; |
---|
| 365 | while (fname && isspace(at(tos, fname))) |
---|
| 366 | fname --; |
---|
| 367 | while (fname && !isspace(at(tos,fname)) && at(tos,fname) != '*') |
---|
| 368 | fname--; |
---|
| 369 | |
---|
| 370 | fname++; |
---|
| 371 | |
---|
| 372 | for (idx = 0; idx < fname; idx++) |
---|
| 373 | { |
---|
| 374 | catchar(&out, at(tos,idx)); |
---|
| 375 | } |
---|
| 376 | |
---|
| 377 | cattext(&out,"EXFUN("); |
---|
| 378 | for (idx = fname; idx < openp; idx++) |
---|
| 379 | { |
---|
| 380 | catchar(&out, at(tos,idx)); |
---|
| 381 | } |
---|
| 382 | cattext(&out,", "); |
---|
| 383 | while (at(tos,idx) && at(tos,idx) !=';') |
---|
| 384 | { |
---|
| 385 | catchar(&out, at(tos, idx)); |
---|
| 386 | idx++; |
---|
| 387 | } |
---|
| 388 | cattext(&out,");\n"); |
---|
| 389 | } |
---|
| 390 | overwrite_string(tos, &out); |
---|
| 391 | pc++; |
---|
| 392 | |
---|
| 393 | } |
---|
| 394 | |
---|
| 395 | |
---|
| 396 | |
---|
| 397 | /* turn {* |
---|
| 398 | and *} into comments */ |
---|
| 399 | |
---|
| 400 | WORD(translatecomments) |
---|
| 401 | { |
---|
| 402 | unsigned int idx = 0; |
---|
| 403 | string_type out; |
---|
| 404 | init_string(&out); |
---|
| 405 | |
---|
| 406 | while (at(tos, idx)) |
---|
| 407 | { |
---|
| 408 | if (at(tos,idx) == '{' && at(tos,idx+1) =='*') |
---|
| 409 | { |
---|
| 410 | cattext(&out," /*"); |
---|
| 411 | idx+=2; |
---|
| 412 | } |
---|
| 413 | else if (at(tos,idx) == '*' && at(tos,idx+1) =='}') |
---|
| 414 | { |
---|
| 415 | cattext(&out,"*/"); |
---|
| 416 | idx+=2; |
---|
| 417 | } |
---|
| 418 | else |
---|
| 419 | { |
---|
| 420 | catchar(&out, at(tos, idx)); |
---|
| 421 | idx++; |
---|
| 422 | } |
---|
| 423 | } |
---|
| 424 | |
---|
| 425 | |
---|
| 426 | overwrite_string(tos, &out); |
---|
| 427 | |
---|
| 428 | pc++; |
---|
| 429 | |
---|
| 430 | } |
---|
| 431 | |
---|
| 432 | #if 0 |
---|
| 433 | /* turn everything not starting with a . into a comment */ |
---|
| 434 | |
---|
| 435 | WORD(manglecomments) |
---|
| 436 | { |
---|
| 437 | unsigned int idx = 0; |
---|
| 438 | string_type out; |
---|
| 439 | init_string(&out); |
---|
| 440 | |
---|
| 441 | while (at(tos, idx)) |
---|
| 442 | { |
---|
| 443 | if (at(tos,idx) == '\n' && at(tos,idx+1) =='*') |
---|
| 444 | { |
---|
| 445 | cattext(&out," /*"); |
---|
| 446 | idx+=2; |
---|
| 447 | } |
---|
| 448 | else if (at(tos,idx) == '*' && at(tos,idx+1) =='}') |
---|
| 449 | { |
---|
| 450 | cattext(&out,"*/"); |
---|
| 451 | idx+=2; |
---|
| 452 | } |
---|
| 453 | else |
---|
| 454 | { |
---|
| 455 | catchar(&out, at(tos, idx)); |
---|
| 456 | idx++; |
---|
| 457 | } |
---|
| 458 | } |
---|
| 459 | |
---|
| 460 | |
---|
| 461 | overwrite_string(tos, &out); |
---|
| 462 | |
---|
| 463 | pc++; |
---|
| 464 | |
---|
| 465 | } |
---|
| 466 | #endif |
---|
| 467 | |
---|
| 468 | /* Mod tos so that only lines with leading dots remain */ |
---|
| 469 | static void |
---|
| 470 | outputdots (void) |
---|
| 471 | { |
---|
| 472 | unsigned int idx = 0; |
---|
| 473 | string_type out; |
---|
| 474 | init_string(&out); |
---|
| 475 | |
---|
| 476 | while (at(tos, idx)) |
---|
| 477 | { |
---|
| 478 | if (at(tos, idx) == '\n' && at(tos, idx+1) == '.') |
---|
| 479 | { |
---|
| 480 | idx += 2; |
---|
| 481 | |
---|
| 482 | while (at(tos, idx) && at(tos, idx)!='\n') |
---|
| 483 | { |
---|
| 484 | if (at(tos,idx) == '{' && at(tos,idx+1) =='*') |
---|
| 485 | { |
---|
| 486 | cattext(&out," /*"); |
---|
| 487 | idx+=2; |
---|
| 488 | } |
---|
| 489 | else if (at(tos,idx) == '*' && at(tos,idx+1) =='}') |
---|
| 490 | { |
---|
| 491 | cattext(&out,"*/"); |
---|
| 492 | idx+=2; |
---|
| 493 | } |
---|
| 494 | else |
---|
| 495 | { |
---|
| 496 | catchar(&out, at(tos, idx)); |
---|
| 497 | idx++; |
---|
| 498 | } |
---|
| 499 | } |
---|
| 500 | catchar(&out,'\n'); |
---|
| 501 | } |
---|
| 502 | else |
---|
| 503 | { |
---|
| 504 | idx++; |
---|
| 505 | } |
---|
| 506 | } |
---|
| 507 | |
---|
| 508 | overwrite_string(tos, &out); |
---|
| 509 | pc++; |
---|
| 510 | |
---|
| 511 | } |
---|
| 512 | |
---|
| 513 | /* Find lines starting with . and | and put example around them on tos |
---|
| 514 | turn |
---|
| 515 | {* into open comment and *} into close comment |
---|
| 516 | escape curlies |
---|
| 517 | |
---|
| 518 | */ |
---|
| 519 | WORD(courierize) |
---|
| 520 | { |
---|
| 521 | string_type out; |
---|
| 522 | unsigned int idx = 0; |
---|
| 523 | |
---|
| 524 | init_string(&out); |
---|
| 525 | |
---|
| 526 | while (at(tos, idx)) |
---|
| 527 | { |
---|
| 528 | if (at(tos, idx) == '\n' |
---|
| 529 | && (at(tos, idx +1 ) == '.' |
---|
| 530 | || at(tos,idx+1) == '|')) |
---|
| 531 | { |
---|
| 532 | cattext(&out,"\n@smallexample\n"); |
---|
| 533 | do |
---|
| 534 | { |
---|
| 535 | idx += 2; |
---|
| 536 | |
---|
| 537 | while (at(tos, idx) && at(tos, idx)!='\n') |
---|
| 538 | { |
---|
| 539 | if (at(tos,idx)=='{' && at(tos,idx+1) =='*') |
---|
| 540 | { |
---|
| 541 | cattext(&out," /*"); |
---|
| 542 | idx+=2; |
---|
| 543 | } |
---|
| 544 | else if (at(tos,idx)=='*' && at(tos,idx+1) =='}') |
---|
| 545 | { |
---|
| 546 | cattext(&out,"*/"); |
---|
| 547 | idx+=2; |
---|
| 548 | } |
---|
| 549 | else if (at(tos,idx) == '{') |
---|
| 550 | { |
---|
| 551 | cattext(&out,"@{"); |
---|
| 552 | idx++; |
---|
| 553 | } |
---|
| 554 | else if (at(tos,idx) == '}') |
---|
| 555 | { |
---|
| 556 | cattext(&out,"@}"); |
---|
| 557 | idx++; |
---|
| 558 | } |
---|
| 559 | else |
---|
| 560 | { |
---|
| 561 | catchar(&out, at(tos, idx)); |
---|
| 562 | idx++; |
---|
| 563 | } |
---|
| 564 | |
---|
| 565 | } |
---|
| 566 | catchar(&out,'\n'); |
---|
| 567 | } |
---|
| 568 | while (at(tos, idx) == '\n' |
---|
| 569 | && (at(tos, idx+1) == '.') |
---|
| 570 | || (at(tos,idx+1) == '|')); |
---|
| 571 | cattext(&out,"@end smallexample"); |
---|
| 572 | } |
---|
| 573 | else |
---|
| 574 | { |
---|
| 575 | catchar(&out, at(tos, idx)); |
---|
| 576 | idx++; |
---|
| 577 | } |
---|
| 578 | } |
---|
| 579 | |
---|
| 580 | overwrite_string(tos, &out); |
---|
| 581 | pc++; |
---|
| 582 | |
---|
| 583 | |
---|
| 584 | } |
---|
| 585 | |
---|
| 586 | /* |
---|
| 587 | bulletize: look for bullet item commands at start of line |
---|
| 588 | Bullet list: |
---|
| 589 | O+ emit @itemize @bullet |
---|
| 590 | o emit @item [note lowercase] |
---|
| 591 | O- emit @end itemize |
---|
| 592 | |
---|
| 593 | Variable label list: |
---|
| 594 | o+ emit @table @code |
---|
| 595 | o emit @item |
---|
| 596 | o- emit @end table |
---|
| 597 | */ |
---|
| 598 | |
---|
| 599 | |
---|
| 600 | WORD(bulletize) |
---|
| 601 | { |
---|
| 602 | unsigned int idx = 0; |
---|
| 603 | string_type out; |
---|
| 604 | init_string(&out); |
---|
| 605 | |
---|
| 606 | while (at(tos, idx)) { |
---|
| 607 | if (at(tos, idx) == '\n' && at(tos, idx+1) == 'o') |
---|
| 608 | { |
---|
| 609 | if (at(tos,idx+2) == '+') { |
---|
| 610 | cattext(&out,"\n@table @code\n"); |
---|
| 611 | idx+=3; |
---|
| 612 | } |
---|
| 613 | else if (at(tos,idx+2) == '-') { |
---|
| 614 | cattext(&out,"\n@end table\n"); |
---|
| 615 | idx+=3; |
---|
| 616 | } |
---|
| 617 | else if (isspace(at(tos,idx+2))) { |
---|
| 618 | cattext(&out,"\n@item "); |
---|
| 619 | idx+=3; |
---|
| 620 | } |
---|
| 621 | else { |
---|
| 622 | catchar(&out, at(tos, idx)); |
---|
| 623 | idx++; |
---|
| 624 | } |
---|
| 625 | } |
---|
| 626 | |
---|
| 627 | else |
---|
| 628 | if (at(tos, idx) == '\n' && at(tos, idx+1) == 'O') |
---|
| 629 | { |
---|
| 630 | if (at(tos,idx+2) == '+') { |
---|
| 631 | cattext(&out,"\n@itemize @bullet\n"); |
---|
| 632 | idx+=3; |
---|
| 633 | } |
---|
| 634 | |
---|
| 635 | else if (at(tos,idx+2) == '-') { |
---|
| 636 | cattext(&out,"\n@end itemize\n"); |
---|
| 637 | idx+=3; |
---|
| 638 | } |
---|
| 639 | else { |
---|
| 640 | catchar(&out, at(tos, idx)); |
---|
| 641 | idx++; |
---|
| 642 | } |
---|
| 643 | } |
---|
| 644 | else |
---|
| 645 | { |
---|
| 646 | catchar(&out, at(tos, idx)); |
---|
| 647 | idx++; |
---|
| 648 | } |
---|
| 649 | } |
---|
| 650 | |
---|
| 651 | delete_string(tos); |
---|
| 652 | *tos = out; |
---|
| 653 | pc++; |
---|
| 654 | |
---|
| 655 | } |
---|
| 656 | |
---|
| 657 | /* Turn <<foo>> into @code{foo} in place at TOS |
---|
| 658 | Turn <[foo]> into @var{foo} in place at TOS |
---|
| 659 | nest them too ! |
---|
| 660 | |
---|
| 661 | */ |
---|
| 662 | |
---|
| 663 | |
---|
| 664 | WORD(do_fancy_stuff) |
---|
| 665 | { |
---|
| 666 | unsigned int idx = 0; |
---|
| 667 | string_type out; |
---|
| 668 | init_string(&out); |
---|
| 669 | while (at(tos, idx)) |
---|
| 670 | { |
---|
| 671 | if (at(tos, idx) == '<' |
---|
| 672 | && at(tos, idx+1) == '<' |
---|
| 673 | && (!isspace(at(tos,idx + 2)) || at(tos,idx+3) == '>')) |
---|
| 674 | { |
---|
| 675 | /* This qualifies as a << startup */ |
---|
| 676 | idx +=2; |
---|
| 677 | cattext(&out,"@code{"); |
---|
| 678 | } |
---|
| 679 | |
---|
| 680 | else if (at(tos, idx) == '<' |
---|
| 681 | && at(tos, idx+1) == '[' |
---|
| 682 | && !isspace(at(tos,idx + 2))) |
---|
| 683 | { |
---|
| 684 | /* This qualifies as a <[ startup */ |
---|
| 685 | idx +=2; |
---|
| 686 | cattext(&out,"@var{"); |
---|
| 687 | } |
---|
| 688 | else if (at(tos, idx) == '>' |
---|
| 689 | && at(tos,idx+1) =='>') |
---|
| 690 | { |
---|
| 691 | |
---|
| 692 | cattext(&out,"}"); |
---|
| 693 | idx+=2; |
---|
| 694 | } |
---|
| 695 | else if (at(tos, idx) == ']' |
---|
| 696 | && at(tos,idx+1) =='>') |
---|
| 697 | { |
---|
| 698 | cattext(&out,"}"); |
---|
| 699 | idx+=2; |
---|
| 700 | } |
---|
| 701 | else |
---|
| 702 | { |
---|
| 703 | catchar(&out, at(tos, idx)); |
---|
| 704 | idx++; |
---|
| 705 | } |
---|
| 706 | } |
---|
| 707 | delete_string(tos); |
---|
| 708 | *tos = out; |
---|
| 709 | pc++; |
---|
| 710 | |
---|
| 711 | } |
---|
| 712 | /* A command is all upper case,and alone on a line */ |
---|
| 713 | static int |
---|
| 714 | iscommand (string_type *ptr, unsigned int idx) |
---|
| 715 | { |
---|
| 716 | unsigned int len = 0; |
---|
| 717 | |
---|
| 718 | while (isupper(at(ptr,idx)) || at(ptr,idx) == '_') { |
---|
| 719 | len++; |
---|
| 720 | idx++; |
---|
| 721 | } |
---|
| 722 | |
---|
| 723 | while (at(ptr,idx) == ' ') { |
---|
| 724 | len++; |
---|
| 725 | idx++; |
---|
| 726 | } |
---|
| 727 | |
---|
| 728 | if(at(ptr,idx) == '\n') |
---|
| 729 | { |
---|
| 730 | /* The length check will never fail on a real command |
---|
| 731 | * because the commands are screened as the definitions file |
---|
| 732 | * is read. */ |
---|
| 733 | if (len >= MIN_CMDLEN) return 1; |
---|
| 734 | return 0; |
---|
| 735 | } |
---|
| 736 | |
---|
| 737 | return 0; |
---|
| 738 | |
---|
| 739 | } |
---|
| 740 | |
---|
| 741 | |
---|
| 742 | unsigned int |
---|
| 743 | copy_past_newline (string_type *ptr, unsigned int idx, string_type *dst) |
---|
| 744 | { |
---|
| 745 | while (at(ptr, idx) && at(ptr, idx) != '\n') |
---|
| 746 | { |
---|
| 747 | catchar(dst, at(ptr, idx)); |
---|
| 748 | idx++; |
---|
| 749 | |
---|
| 750 | } |
---|
| 751 | catchar(dst, at(ptr, idx)); |
---|
| 752 | idx++; |
---|
| 753 | return idx; |
---|
| 754 | |
---|
| 755 | } |
---|
| 756 | |
---|
| 757 | WORD(icopy_past_newline) |
---|
| 758 | { |
---|
| 759 | tos++; |
---|
| 760 | init_string(tos); |
---|
| 761 | idx = copy_past_newline(ptr, idx, tos); |
---|
| 762 | pc++; |
---|
| 763 | } |
---|
| 764 | |
---|
| 765 | |
---|
| 766 | /* indent |
---|
| 767 | Take the string at the top of the stack, do some prettying */ |
---|
| 768 | |
---|
| 769 | |
---|
| 770 | |
---|
| 771 | |
---|
| 772 | WORD(kill_bogus_lines) |
---|
| 773 | { |
---|
| 774 | int sl ; |
---|
| 775 | |
---|
| 776 | int idx = 0; |
---|
| 777 | int c; |
---|
| 778 | int dot = 0 ; |
---|
| 779 | |
---|
| 780 | string_type out; |
---|
| 781 | init_string(&out); |
---|
| 782 | /* Drop leading nl */ |
---|
| 783 | while (at(tos,idx) == '\n') |
---|
| 784 | { |
---|
| 785 | idx++; |
---|
| 786 | } |
---|
| 787 | c = idx; |
---|
| 788 | |
---|
| 789 | /* Find the last char */ |
---|
| 790 | while (at(tos,idx)) |
---|
| 791 | { |
---|
| 792 | idx++; |
---|
| 793 | } |
---|
| 794 | |
---|
| 795 | /* find the last non white before the nl */ |
---|
| 796 | idx--; |
---|
| 797 | |
---|
| 798 | while (idx && isspace(at(tos,idx))) |
---|
| 799 | idx--; |
---|
| 800 | idx++; |
---|
| 801 | |
---|
| 802 | /* Copy buffer upto last char, but blank lines before and after |
---|
| 803 | dots don't count */ |
---|
| 804 | sl = 1; |
---|
| 805 | |
---|
| 806 | while (c < idx) |
---|
| 807 | { |
---|
| 808 | if (at(tos,c) == '\n' |
---|
| 809 | && at(tos,c+1) == '\n' |
---|
| 810 | && at(tos,c+2) == '.') |
---|
| 811 | { |
---|
| 812 | /* Ignore two linelines before a dot*/ |
---|
| 813 | c++; |
---|
| 814 | } |
---|
| 815 | else if (at(tos,c) == '.' && sl) |
---|
| 816 | { |
---|
| 817 | /* remember that this line started with a dot */ |
---|
| 818 | dot=2; |
---|
| 819 | } |
---|
| 820 | else if (at(tos,c) == '\n' |
---|
| 821 | && at(tos,c+1) == '\n' |
---|
| 822 | && dot) |
---|
| 823 | { |
---|
| 824 | c++; |
---|
| 825 | /* Ignore two newlines when last line was dot */ |
---|
| 826 | } |
---|
| 827 | |
---|
| 828 | catchar(&out, at(tos,c)); |
---|
| 829 | if (at(tos,c) == '\n') |
---|
| 830 | { |
---|
| 831 | sl = 1; |
---|
| 832 | |
---|
| 833 | if (dot == 2)dot=1;else dot = 0; |
---|
| 834 | } |
---|
| 835 | |
---|
| 836 | c++; |
---|
| 837 | |
---|
| 838 | } |
---|
| 839 | |
---|
| 840 | /* Append nl*/ |
---|
| 841 | catchar(&out, '\n'); |
---|
| 842 | pc++; |
---|
| 843 | delete_string(tos); |
---|
| 844 | *tos = out; |
---|
| 845 | |
---|
| 846 | |
---|
| 847 | } |
---|
| 848 | |
---|
| 849 | WORD(indent) |
---|
| 850 | { |
---|
| 851 | string_type out; |
---|
| 852 | int tab = 0; |
---|
| 853 | int idx = 0; |
---|
| 854 | int ol =0; |
---|
| 855 | init_string(&out); |
---|
| 856 | while (at(tos,idx)) { |
---|
| 857 | switch (at(tos,idx)) |
---|
| 858 | { |
---|
| 859 | case '\n': |
---|
| 860 | cattext(&out,"\n"); |
---|
| 861 | idx++; |
---|
| 862 | if (tab) |
---|
| 863 | { |
---|
| 864 | cattext(&out," "); |
---|
| 865 | } |
---|
| 866 | ol = 0; |
---|
| 867 | break; |
---|
| 868 | case '(': |
---|
| 869 | tab++; |
---|
| 870 | if (ol == 0) |
---|
| 871 | cattext(&out," "); |
---|
| 872 | idx++; |
---|
| 873 | cattext(&out,"("); |
---|
| 874 | ol = 1; |
---|
| 875 | break; |
---|
| 876 | case ')': |
---|
| 877 | tab--; |
---|
| 878 | cattext(&out,")"); |
---|
| 879 | idx++; |
---|
| 880 | ol=1; |
---|
| 881 | |
---|
| 882 | break; |
---|
| 883 | default: |
---|
| 884 | catchar(&out,at(tos,idx)); |
---|
| 885 | ol=1; |
---|
| 886 | |
---|
| 887 | idx++; |
---|
| 888 | break; |
---|
| 889 | } |
---|
| 890 | } |
---|
| 891 | |
---|
| 892 | pc++; |
---|
| 893 | delete_string(tos); |
---|
| 894 | *tos = out; |
---|
| 895 | |
---|
| 896 | } |
---|
| 897 | |
---|
| 898 | /* Change the TOS so that all that is left is the stuff inside the |
---|
| 899 | first <<foo>> . |
---|
| 900 | */ |
---|
| 901 | |
---|
| 902 | WORD(get_stuff_in_angle) |
---|
| 903 | { |
---|
| 904 | unsigned int idx = 0; |
---|
| 905 | string_type out; |
---|
| 906 | init_string(&out); |
---|
| 907 | |
---|
| 908 | while (at(tos, idx)) |
---|
| 909 | { |
---|
| 910 | if (at(tos,idx) == '<' && at(tos,idx+1) =='<') |
---|
| 911 | { |
---|
| 912 | idx+=2; |
---|
| 913 | |
---|
| 914 | while (!(at(tos,idx) == '>' && at(tos,idx+1) == '>')) |
---|
| 915 | { |
---|
| 916 | catchar(&out, at(tos, idx)); |
---|
| 917 | idx++; |
---|
| 918 | } |
---|
| 919 | break; |
---|
| 920 | } |
---|
| 921 | idx++; |
---|
| 922 | } |
---|
| 923 | catchar(&out,'\n'); |
---|
| 924 | |
---|
| 925 | overwrite_string(tos, &out); |
---|
| 926 | pc++; |
---|
| 927 | } |
---|
| 928 | |
---|
| 929 | |
---|
| 930 | WORD(get_stuff_in_command) |
---|
| 931 | { |
---|
| 932 | tos++; |
---|
| 933 | init_string(tos); |
---|
| 934 | |
---|
| 935 | while (at(ptr, idx)) { |
---|
| 936 | if (iscommand(ptr, idx)) break; |
---|
| 937 | idx = copy_past_newline(ptr, idx, tos); |
---|
| 938 | } |
---|
| 939 | pc++; |
---|
| 940 | } |
---|
| 941 | |
---|
| 942 | WORD(swap) |
---|
| 943 | { |
---|
| 944 | string_type t; |
---|
| 945 | |
---|
| 946 | t = tos[0]; |
---|
| 947 | tos[0] = tos[-1]; |
---|
| 948 | tos[-1] =t; |
---|
| 949 | pc++; |
---|
| 950 | |
---|
| 951 | } |
---|
| 952 | |
---|
| 953 | WORD(dup_) |
---|
| 954 | { |
---|
| 955 | tos++; |
---|
| 956 | init_string(tos); |
---|
| 957 | catstr(tos, tos-1); |
---|
| 958 | pc++; |
---|
| 959 | |
---|
| 960 | } |
---|
| 961 | |
---|
| 962 | |
---|
| 963 | |
---|
| 964 | WORD(icatstr) |
---|
| 965 | { |
---|
| 966 | catstr(tos-1, tos); |
---|
| 967 | delete_string(tos); |
---|
| 968 | tos--; |
---|
| 969 | pc++; |
---|
| 970 | |
---|
| 971 | } |
---|
| 972 | |
---|
| 973 | WORD(skip_past_newline) |
---|
| 974 | { |
---|
| 975 | while (at(ptr,idx) |
---|
| 976 | && at(ptr,idx) != '\n') |
---|
| 977 | idx++; |
---|
| 978 | idx++; |
---|
| 979 | pc++; |
---|
| 980 | } |
---|
| 981 | |
---|
| 982 | |
---|
| 983 | WORD(internalmode) |
---|
| 984 | { |
---|
| 985 | internal_mode = *(isp); |
---|
| 986 | isp--; |
---|
| 987 | pc++; |
---|
| 988 | } |
---|
| 989 | |
---|
| 990 | WORD(maybecatstr) |
---|
| 991 | { |
---|
| 992 | if (internal_wanted == internal_mode) |
---|
| 993 | { |
---|
| 994 | catstr(tos-1, tos); |
---|
| 995 | } |
---|
| 996 | delete_string(tos); |
---|
| 997 | tos--; |
---|
| 998 | pc++; |
---|
| 999 | |
---|
| 1000 | } |
---|
| 1001 | |
---|
| 1002 | /* write tos to stderr */ |
---|
| 1003 | WORD(warn) |
---|
| 1004 | { |
---|
| 1005 | fputs("Warning: ", stderr); |
---|
| 1006 | fwrite(tos->ptr, tos->write_idx, 1, stderr); |
---|
| 1007 | fputc('\n', stderr); |
---|
| 1008 | delete_string(tos); |
---|
| 1009 | tos--; |
---|
| 1010 | pc++; |
---|
| 1011 | } |
---|
| 1012 | |
---|
| 1013 | char * |
---|
| 1014 | nextword (char *string, char **word) |
---|
| 1015 | { |
---|
| 1016 | char *word_start; |
---|
| 1017 | int idx; |
---|
| 1018 | char *dst; |
---|
| 1019 | char *src; |
---|
| 1020 | |
---|
| 1021 | int length = 0; |
---|
| 1022 | |
---|
| 1023 | while (isspace(*string) || *string == '-') { |
---|
| 1024 | if (*string == '-') |
---|
| 1025 | { |
---|
| 1026 | while (*string && *string != '\n') |
---|
| 1027 | string++; |
---|
| 1028 | |
---|
| 1029 | } |
---|
| 1030 | else { |
---|
| 1031 | string++; |
---|
| 1032 | } |
---|
| 1033 | } |
---|
| 1034 | if (!*string) return 0; |
---|
| 1035 | |
---|
| 1036 | word_start = string; |
---|
| 1037 | if (*string == '"') |
---|
| 1038 | { |
---|
| 1039 | string++; |
---|
| 1040 | length++; |
---|
| 1041 | |
---|
| 1042 | while (*string != '"') |
---|
| 1043 | { |
---|
| 1044 | string++; |
---|
| 1045 | length++; |
---|
| 1046 | } |
---|
| 1047 | } |
---|
| 1048 | else |
---|
| 1049 | { |
---|
| 1050 | |
---|
| 1051 | |
---|
| 1052 | while (!isspace(*string)) |
---|
| 1053 | { |
---|
| 1054 | string++; |
---|
| 1055 | length++; |
---|
| 1056 | } |
---|
| 1057 | } |
---|
| 1058 | |
---|
| 1059 | *word = malloc(length + 1); |
---|
| 1060 | |
---|
| 1061 | dst = *word; |
---|
| 1062 | src = word_start; |
---|
| 1063 | |
---|
| 1064 | |
---|
| 1065 | for (idx= 0; idx < length; idx++) |
---|
| 1066 | { |
---|
| 1067 | |
---|
| 1068 | if (src[idx] == '\\' && src[idx+1] == 'n') |
---|
| 1069 | { |
---|
| 1070 | *dst++ = '\n'; |
---|
| 1071 | idx++; |
---|
| 1072 | |
---|
| 1073 | } |
---|
| 1074 | else *dst++ = src[idx]; |
---|
| 1075 | } |
---|
| 1076 | *dst++ = 0; |
---|
| 1077 | |
---|
| 1078 | |
---|
| 1079 | |
---|
| 1080 | |
---|
| 1081 | |
---|
| 1082 | if(*string) |
---|
| 1083 | return string + 1; |
---|
| 1084 | else |
---|
| 1085 | return 0; |
---|
| 1086 | |
---|
| 1087 | } |
---|
| 1088 | dict_type *root; |
---|
| 1089 | dict_type * |
---|
| 1090 | lookup_word (char *word) |
---|
| 1091 | { |
---|
| 1092 | dict_type *ptr = root; |
---|
| 1093 | while (ptr) { |
---|
| 1094 | if (strcmp(ptr->word, word) == 0) return ptr; |
---|
| 1095 | ptr = ptr->next; |
---|
| 1096 | |
---|
| 1097 | } |
---|
| 1098 | fprintf(stderr,"Can't find %s\n",word); |
---|
| 1099 | return 0; |
---|
| 1100 | |
---|
| 1101 | |
---|
| 1102 | } |
---|
| 1103 | |
---|
| 1104 | static int |
---|
| 1105 | perform (void) |
---|
| 1106 | { |
---|
| 1107 | tos = stack; |
---|
| 1108 | int errors = 0; |
---|
| 1109 | |
---|
| 1110 | while (at(ptr, idx)) { |
---|
| 1111 | /* It's worth looking through the command list */ |
---|
| 1112 | if (iscommand(ptr, idx)) |
---|
| 1113 | { |
---|
| 1114 | char *next; |
---|
| 1115 | dict_type *word ; |
---|
| 1116 | |
---|
| 1117 | (void) nextword(addr(ptr, idx), &next); |
---|
| 1118 | |
---|
| 1119 | |
---|
| 1120 | word = lookup_word(next); |
---|
| 1121 | |
---|
| 1122 | |
---|
| 1123 | |
---|
| 1124 | |
---|
| 1125 | if (word) |
---|
| 1126 | { |
---|
| 1127 | if(Verbose) fprintf(stderr, "CMD '%s'\n", word->word); |
---|
| 1128 | exec(word); |
---|
| 1129 | } |
---|
| 1130 | else |
---|
| 1131 | { |
---|
| 1132 | fprintf(stderr,"warning, %s is not recognised\n", next); |
---|
| 1133 | errors++; |
---|
| 1134 | skip_past_newline(); |
---|
| 1135 | } |
---|
| 1136 | |
---|
| 1137 | } |
---|
| 1138 | else skip_past_newline(); |
---|
| 1139 | |
---|
| 1140 | } |
---|
| 1141 | return errors; |
---|
| 1142 | } |
---|
| 1143 | |
---|
| 1144 | dict_type * |
---|
| 1145 | newentry (char *word) |
---|
| 1146 | { |
---|
| 1147 | dict_type *new = (dict_type *)malloc(sizeof(dict_type)); |
---|
| 1148 | new->word = word; |
---|
| 1149 | new->next = root; |
---|
| 1150 | root = new; |
---|
| 1151 | new->code = (stinst_type *)malloc(sizeof(stinst_type )); |
---|
| 1152 | new->code_length = 1; |
---|
| 1153 | new->code_end = 0; |
---|
| 1154 | return new; |
---|
| 1155 | |
---|
| 1156 | } |
---|
| 1157 | |
---|
| 1158 | |
---|
| 1159 | unsigned int |
---|
| 1160 | add_to_definition (dict_type *entry, stinst_type word) |
---|
| 1161 | { |
---|
| 1162 | if (entry->code_end == entry->code_length) |
---|
| 1163 | { |
---|
| 1164 | entry->code_length += 2; |
---|
| 1165 | entry->code = |
---|
| 1166 | (stinst_type *) realloc((char *)(entry->code), |
---|
| 1167 | entry->code_length *sizeof(word_type)); |
---|
| 1168 | } |
---|
| 1169 | entry->code[entry->code_end] = word; |
---|
| 1170 | |
---|
| 1171 | return entry->code_end++; |
---|
| 1172 | } |
---|
| 1173 | |
---|
| 1174 | |
---|
| 1175 | |
---|
| 1176 | |
---|
| 1177 | |
---|
| 1178 | |
---|
| 1179 | |
---|
| 1180 | void |
---|
| 1181 | add_intrinsic (char *name, void (*func)(void)) |
---|
| 1182 | { |
---|
| 1183 | dict_type *new = newentry(name); |
---|
| 1184 | add_to_definition(new, func); |
---|
| 1185 | add_to_definition(new, 0); |
---|
| 1186 | } |
---|
| 1187 | |
---|
| 1188 | void |
---|
| 1189 | add_var (char *name) |
---|
| 1190 | { |
---|
| 1191 | dict_type *new = newentry(name); |
---|
| 1192 | add_to_definition(new, push_number); |
---|
| 1193 | add_to_definition(new, (stinst_type)(&(new->var))); |
---|
| 1194 | add_to_definition(new,0); |
---|
| 1195 | |
---|
| 1196 | } |
---|
| 1197 | |
---|
| 1198 | |
---|
| 1199 | |
---|
| 1200 | |
---|
| 1201 | int |
---|
| 1202 | compile (char *string) |
---|
| 1203 | { |
---|
| 1204 | int ret=0; |
---|
| 1205 | /* add words to the dictionary */ |
---|
| 1206 | char *word; |
---|
| 1207 | dict_type *lookup; |
---|
| 1208 | |
---|
| 1209 | string = nextword(string, &word); |
---|
| 1210 | while (string && *string && word[0]) |
---|
| 1211 | { |
---|
| 1212 | if (strcmp(word,"var")==0) |
---|
| 1213 | { |
---|
| 1214 | string=nextword(string, &word); |
---|
| 1215 | |
---|
| 1216 | add_var(word); |
---|
| 1217 | string=nextword(string, &word); |
---|
| 1218 | } |
---|
| 1219 | else |
---|
| 1220 | |
---|
| 1221 | if (word[0] == ':') |
---|
| 1222 | { |
---|
| 1223 | dict_type *ptr; |
---|
| 1224 | /* Compile a word and add to dictionary */ |
---|
| 1225 | string = nextword(string, &word); |
---|
| 1226 | if(Verbose) fprintf(stderr, "Found command '%s'\n", word); |
---|
| 1227 | if(strlen(word) < MIN_CMDLEN) { |
---|
| 1228 | fprintf(stderr, "ERROR: Command '%s' is too short ", word); |
---|
| 1229 | fprintf(stderr, "(MIN_CMDLEN is %d)\n", MIN_CMDLEN); |
---|
| 1230 | ret++; |
---|
| 1231 | } |
---|
| 1232 | |
---|
| 1233 | ptr = newentry(word); |
---|
| 1234 | string = nextword(string, &word); |
---|
| 1235 | while (word[0] != ';' ) |
---|
| 1236 | { |
---|
| 1237 | switch (word[0]) |
---|
| 1238 | { |
---|
| 1239 | |
---|
| 1240 | |
---|
| 1241 | case '"': |
---|
| 1242 | /* got a string, embed magic push string |
---|
| 1243 | function */ |
---|
| 1244 | add_to_definition(ptr, push_text); |
---|
| 1245 | add_to_definition(ptr, (stinst_type)(word+1)); |
---|
| 1246 | break; |
---|
| 1247 | case '0': |
---|
| 1248 | case '1': |
---|
| 1249 | case '2': |
---|
| 1250 | case '3': |
---|
| 1251 | case '4': |
---|
| 1252 | case '5': |
---|
| 1253 | case '6': |
---|
| 1254 | case '7': |
---|
| 1255 | case '8': |
---|
| 1256 | case '9': |
---|
| 1257 | /* Got a number, embedd the magic push number |
---|
| 1258 | function */ |
---|
| 1259 | add_to_definition(ptr, push_number); |
---|
| 1260 | add_to_definition(ptr, (stinst_type)atol(word)); |
---|
| 1261 | break; |
---|
| 1262 | default: |
---|
| 1263 | add_to_definition(ptr, call); |
---|
| 1264 | lookup = lookup_word(word); |
---|
| 1265 | if (!lookup) ret++; |
---|
| 1266 | add_to_definition(ptr, (stinst_type)lookup); |
---|
| 1267 | } |
---|
| 1268 | |
---|
| 1269 | string = nextword(string, &word); |
---|
| 1270 | } |
---|
| 1271 | add_to_definition(ptr,0); |
---|
| 1272 | string = nextword(string, &word); |
---|
| 1273 | } |
---|
| 1274 | else |
---|
| 1275 | { |
---|
| 1276 | fprintf(stderr,"syntax error at %s\n",string-1); |
---|
| 1277 | ret++; |
---|
| 1278 | } |
---|
| 1279 | } |
---|
| 1280 | |
---|
| 1281 | return(ret); |
---|
| 1282 | } |
---|
| 1283 | |
---|
| 1284 | |
---|
| 1285 | static void |
---|
| 1286 | bang (void) |
---|
| 1287 | { |
---|
| 1288 | *(uintptr_t *)((isp[0])) = isp[-1]; |
---|
| 1289 | isp-=2; |
---|
| 1290 | pc++; |
---|
| 1291 | |
---|
| 1292 | } |
---|
| 1293 | |
---|
| 1294 | WORD(atsign) |
---|
| 1295 | { |
---|
| 1296 | isp[0] = *(uintptr_t *)(isp[0]); |
---|
| 1297 | pc++; |
---|
| 1298 | } |
---|
| 1299 | |
---|
| 1300 | WORD(hello) |
---|
| 1301 | { |
---|
| 1302 | |
---|
| 1303 | printf("hello\n"); |
---|
| 1304 | pc++; |
---|
| 1305 | } |
---|
| 1306 | |
---|
| 1307 | |
---|
| 1308 | |
---|
| 1309 | static void |
---|
| 1310 | read_in (string_type *str, FILE *file) |
---|
| 1311 | { |
---|
| 1312 | char buff[10000]; |
---|
| 1313 | unsigned int r; |
---|
| 1314 | do |
---|
| 1315 | { |
---|
| 1316 | r = fread(buff, 1, sizeof(buff), file); |
---|
| 1317 | catbuf(str, buff, r); |
---|
| 1318 | } |
---|
| 1319 | while (r); |
---|
| 1320 | buff[0] = 0; |
---|
| 1321 | |
---|
| 1322 | catbuf(str, buff,1); |
---|
| 1323 | |
---|
| 1324 | } |
---|
| 1325 | |
---|
| 1326 | |
---|
| 1327 | #if 0 |
---|
| 1328 | static void |
---|
| 1329 | usage (void) |
---|
| 1330 | { |
---|
| 1331 | fprintf(stderr,"usage: -[i|v] -f macrofile <file >file\n"); |
---|
| 1332 | exit(33); |
---|
| 1333 | } |
---|
| 1334 | #endif |
---|
| 1335 | |
---|
| 1336 | int |
---|
| 1337 | main (int ac, char *av[]) |
---|
| 1338 | { |
---|
| 1339 | unsigned int i; |
---|
| 1340 | int status = 0; |
---|
| 1341 | |
---|
| 1342 | string_type buffer; |
---|
| 1343 | string_type pptr; |
---|
| 1344 | |
---|
| 1345 | |
---|
| 1346 | init_string(&buffer); |
---|
| 1347 | init_string(&pptr); |
---|
| 1348 | init_string(stack+0); |
---|
| 1349 | tos=stack+1; |
---|
| 1350 | ptr = &pptr; |
---|
| 1351 | |
---|
| 1352 | add_intrinsic("push_text", push_text); |
---|
| 1353 | add_intrinsic("!", bang); |
---|
| 1354 | add_intrinsic("@", atsign); |
---|
| 1355 | add_intrinsic("hello",hello); |
---|
| 1356 | add_intrinsic("skip_past_newline", skip_past_newline ); |
---|
| 1357 | add_intrinsic("catstr", icatstr ); |
---|
| 1358 | add_intrinsic("copy_past_newline", icopy_past_newline ); |
---|
| 1359 | add_intrinsic("dup", dup_ ); |
---|
| 1360 | add_intrinsic("remchar", remchar ); |
---|
| 1361 | add_intrinsic("get_stuff_in_command", get_stuff_in_command ); |
---|
| 1362 | add_intrinsic("get_stuff_in_angle", get_stuff_in_angle ); |
---|
| 1363 | add_intrinsic("do_fancy_stuff", do_fancy_stuff ); |
---|
| 1364 | add_intrinsic("bulletize", bulletize ); |
---|
| 1365 | add_intrinsic("courierize", courierize ); |
---|
| 1366 | add_intrinsic("swap", swap ); |
---|
| 1367 | add_intrinsic("outputdots", outputdots ); |
---|
| 1368 | add_intrinsic("exfunstuff", exfunstuff ); |
---|
| 1369 | add_intrinsic("maybecatstr", maybecatstr ); |
---|
| 1370 | add_intrinsic("translatecomments", translatecomments ); |
---|
| 1371 | add_intrinsic("kill_bogus_lines", kill_bogus_lines); |
---|
| 1372 | add_intrinsic("indent", indent); |
---|
| 1373 | add_intrinsic("internalmode", internalmode); |
---|
| 1374 | add_intrinsic("warn", warn); |
---|
| 1375 | |
---|
| 1376 | /* Put a nl at the start */ |
---|
| 1377 | catchar(&buffer,'\n'); |
---|
| 1378 | |
---|
| 1379 | read_in(&buffer, stdin); |
---|
| 1380 | remove_noncomments(&buffer, ptr); |
---|
| 1381 | for (i= 1; i < ac; i++) |
---|
| 1382 | { |
---|
| 1383 | if (av[i][0] == '-') |
---|
| 1384 | { |
---|
| 1385 | if (av[i][1] == 'f') |
---|
| 1386 | { |
---|
| 1387 | string_type b; |
---|
| 1388 | FILE *f; |
---|
| 1389 | init_string(&b); |
---|
| 1390 | |
---|
| 1391 | f = fopen(av[i+1],"r"); |
---|
| 1392 | if (!f) |
---|
| 1393 | { |
---|
| 1394 | fprintf(stderr,"Can't open the input file %s\n",av[i+1]); |
---|
| 1395 | return 33; |
---|
| 1396 | } |
---|
| 1397 | if(Verbose) fprintf(stderr, "Reading -f '%s'\n", av[i+1]); |
---|
| 1398 | |
---|
| 1399 | |
---|
| 1400 | read_in(&b, f); |
---|
| 1401 | if( compile(b.ptr) ) { fclose(f); exit(1); } |
---|
| 1402 | status = perform(); |
---|
| 1403 | fclose(f); |
---|
| 1404 | } |
---|
| 1405 | else if (av[i][1] == 'i') |
---|
| 1406 | { |
---|
| 1407 | internal_wanted = 1; |
---|
| 1408 | } |
---|
| 1409 | else if (av[i][1] == 'v') |
---|
| 1410 | { |
---|
| 1411 | Verbose++; |
---|
| 1412 | } |
---|
| 1413 | } |
---|
| 1414 | |
---|
| 1415 | } |
---|
| 1416 | write_buffer(stack+0); |
---|
| 1417 | return status; |
---|
| 1418 | } |
---|