📄 chew.c
字号:
/* chew Copyright (C) 1990-1991 Free Software Foundation, Inc. Contributed by steve chamberlain @cygnusThis file is part of BFD, the Binary File Descriptor library.This program is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2 of the License, or(at your option) any later version.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *//* Yet another way of extracting documentation from source. No, I haven't finished it yet, but I hope you people like it better that the old way sacBasically, this is a sort of string forth, maybe we should call itstruth?You define new words thus:: <newword> <oldwords> ;There is no*/#include <ansidecl.h>#include "sysdep.h"#define DEF_SIZE 5000#define STACK 50int internal_wanted;int internal_mode;int warning;/* Here is a string type ... */typedef struct buffer { char *ptr; unsigned int write_idx; unsigned int size;} string_type;static void DEFUN(init_string_with_size,(buffer, size), string_type *buffer AND unsigned int size ){ buffer->write_idx = 0; buffer->size = size; buffer->ptr = malloc(size);}static void DEFUN(init_string,(buffer), string_type *buffer){ init_string_with_size(buffer, DEF_SIZE);}static int DEFUN(find, (str, what), string_type *str AND char *what){ unsigned int i; char *p; p = what; for (i = 0; i < str->write_idx && *p; i++) { if (*p == str->ptr[i]) p++; else p = what; } return (*p == 0); }static void DEFUN(write_buffer,(buffer), string_type *buffer){ fwrite(buffer->ptr, buffer->write_idx, 1, stdout);}static void DEFUN(delete_string,(buffer), string_type *buffer){ free(buffer->ptr);}static char *DEFUN(addr, (buffer, idx), string_type *buffer AND unsigned int idx){ return buffer->ptr + idx;}static char DEFUN(at,(buffer, pos), string_type *buffer AND unsigned int pos) { if ( pos >= buffer->write_idx) { return 0; } return buffer->ptr[pos];}static void DEFUN(catchar,(buffer, ch), string_type *buffer AND char ch){ if (buffer->write_idx == buffer->size) { buffer->size *=2; buffer->ptr = realloc(buffer->ptr, buffer->size); } buffer->ptr[buffer->write_idx ++ ] = ch;}static void DEFUN(overwrite_string,(dst, src), string_type *dst AND string_type *src){ free(dst->ptr); dst->size = src->size; dst->write_idx = src->write_idx; dst->ptr = src->ptr;}static void DEFUN(catstr,(dst, src), string_type *dst AND string_type *src){ unsigned int i; for (i = 0; i < src->write_idx; i++) { catchar(dst, src->ptr[i]); }}static void DEFUN(cattext,(buffer, string), string_type *buffer AND char *string){ while (*string) { catchar(buffer, *string); string++; }}static void DEFUN(catbuf,(buffer, buf, len), string_type *buffer AND char *buf AND unsigned int len){ while (len--) { catchar(buffer, *buf); buf++; }}static unsigned int DEFUN(skip_white_and_stars,(src, idx), string_type *src AND unsigned int idx){ while (isspace(at(src,idx)) || (at(src,idx) == '*' && at(src,idx +1) !='/' && at(src,idx -1) != '\n')) idx++; return idx; }/***********************************************************************/string_type stack[STACK];string_type *tos;unsigned int idx = 0; /* Pos in input buffer */string_type *ptr; /* and the buffer */typedef void (*stinst_type)();stinst_type *pc;stinst_type sstack[STACK];stinst_type *ssp = &sstack[0];int istack[STACK];int *isp = &istack[0];typedef int *word_type;struct dict_struct{ char *word; struct dict_struct *next; stinst_type *code; int code_length; int code_end; int var; };typedef struct dict_struct dict_type;#define WORD(x) static void x()static void DEFUN(exec,(word), dict_type *word){ pc = word->code; while (*pc) { (*pc)(); } }WORD(call){stinst_type *oldpc = pc; dict_type *e; e = (dict_type *)(pc [1]); exec(e); pc = oldpc + 2; }WORD(remchar){ tos->write_idx--; pc++; }WORD(push_number){ isp++; pc++; *isp = (int)(*pc); pc++; }WORD(push_text){ tos++; init_string(tos); pc++; cattext(tos,*((char **)pc)); pc++; } /* This function removes everything not inside comments starting on the first char of the line from the string, also when copying comments, removes blank space and leading *'s Blank lines are turned into one blank line */static void DEFUN(remove_noncomments,(src,dst), string_type *src AND string_type *dst){ unsigned int idx = 0; while (at(src,idx)) { /* Now see if we have a comment at the start of the line */ if (at(src,idx) == '\n' && at(src,idx+1) == '/' && at(src,idx+2) == '*') { idx+=3; idx = skip_white_and_stars(src,idx); /* Remove leading dot */ if (at(src, idx) == '.') idx++; /* Copy to the end of the line, or till the end of the comment */ while (at(src, idx)) { if (at(src, idx) == '\n') { /* end of line, echo and scrape of leading blanks */ if (at(src,idx +1) == '\n') catchar(dst,'\n'); catchar(dst,'\n'); idx++; idx = skip_white_and_stars(src, idx); } else if (at(src, idx) == '*' && at(src,idx+1) == '/') { idx +=2 ; cattext(dst,"\nENDDD\n"); break; } else { catchar(dst, at(src, idx)); idx++; } } } else idx++; }}/* turn foobar name(stuff); into foobar EXFUN(name,(stuff)); */static voidDEFUN_VOID(exfunstuff){ unsigned int openp; unsigned int fname; unsigned int idx; string_type out; init_string(&out); /* make sure that it's not already exfuned */ if(find(tos,"EXFUN") || find(tos,"PROTO") || !find(tos,"(")) { catstr(&out,tos); } else { /*Find the open paren*/ for (openp = 0; at(tos, openp) != '(' && at(tos,openp); openp++) ; fname = openp; /* Step back to the fname */ fname--; while (fname && isspace(at(tos, fname))) fname --; while (fname && !isspace(at(tos,fname)) && at(tos,fname) != '*') fname--; fname++; for (idx = 0; idx < fname; idx++) { catchar(&out, at(tos,idx)); } cattext(&out,"EXFUN("); for (idx = fname; idx < openp; idx++) { catchar(&out, at(tos,idx)); } cattext(&out,", "); while (at(tos,idx) && at(tos,idx) !=';') { catchar(&out, at(tos, idx)); idx++; } cattext(&out,");\n"); } overwrite_string(tos, &out); pc++; }/* turn {* and *} into comments */WORD(translatecomments){ unsigned int idx = 0; string_type out; init_string(&out); while (at(tos, idx)) { if (at(tos,idx) == '{' && at(tos,idx+1) =='*') { cattext(&out," /*"); idx+=2; } else if (at(tos,idx) == '*' && at(tos,idx+1) =='}') { cattext(&out,"*/"); idx+=2; } else { catchar(&out, at(tos, idx)); idx++; } } overwrite_string(tos, &out); pc++; }/* turn everything not starting with a . into a comment */WORD(manglecomments){ unsigned int idx = 0; string_type out; init_string(&out); while (at(tos, idx)) { if (at(tos,idx) == '\n' && at(tos,idx+1) =='*') { cattext(&out," /*"); idx+=2; } else if (at(tos,idx) == '*' && at(tos,idx+1) =='}') { cattext(&out,"*/"); idx+=2; } else { catchar(&out, at(tos, idx)); idx++; } } overwrite_string(tos, &out); pc++; }/* Mod tos so that only lines with leading dots remain */static voidDEFUN_VOID(outputdots){ unsigned int idx = 0; string_type out; init_string(&out); while (at(tos, idx)) { if (at(tos, idx) == '\n' && at(tos, idx+1) == '.') { idx += 2; while (at(tos, idx) && at(tos, idx)!='\n') { if (at(tos,idx) == '{' && at(tos,idx+1) =='*') { cattext(&out," /*"); idx+=2; } else if (at(tos,idx) == '*' && at(tos,idx+1) =='}') { cattext(&out,"*/"); idx+=2; } else { catchar(&out, at(tos, idx)); idx++; } } catchar(&out,'\n'); } else { idx++; } } overwrite_string(tos, &out); pc++; }/* Find lines starting with . and | and put example around them on tos */WORD(courierize){ string_type out; unsigned int idx = 0; int command = 0; init_string(&out); while (at(tos, idx)) { if (at(tos, idx) == '\n' && (at(tos, idx +1 ) == '.' || at(tos,idx+1) == '|')) { cattext(&out,"\n@example\n"); do { idx += 2; while (at(tos, idx) && at(tos, idx)!='\n') { if (at(tos,idx)=='{' && at(tos,idx+1) =='*') { cattext(&out," /*"); idx+=2; } else if (at(tos,idx)=='*' && at(tos,idx+1) =='}') { cattext(&out,"*/"); idx+=2; } else if (at(tos,idx) == '{' && !command) { cattext(&out,"@{"); idx++; } else if (at(tos,idx) == '}' && !command) { cattext(&out,"@}"); idx++; } else { if (at(tos,idx) == '@') command = 1; else if (isspace(at(tos,idx)) || at(tos,idx) == '}') command = 0; catchar(&out, at(tos, idx)); idx++; } } catchar(&out,'\n'); } while (at(tos, idx) == '\n' && (at(tos, idx+1) == '.') || (at(tos,idx+1) == '|')); cattext(&out,"@end example"); } else { catchar(&out, at(tos, idx)); idx++; } } overwrite_string(tos, &out); pc++; }/* Finds any lines starting with "o ", if there are any, then turns on @itemize @bullet, and @items each of them. Then ends with @end itemize, inplace at TOS*/WORD(bulletize){ unsigned int idx = 0; int on = 0; string_type out; init_string(&out); while (at(tos, idx)) { if (at(tos, idx) == '@' && at(tos, idx+1) == '*') { cattext(&out,"*"); idx+=2; } else if (at(tos, idx) == '\n' && at(tos, idx+1) == 'o' && isspace(at(tos, idx +2))) { if (!on) { cattext(&out,"\n@itemize @bullet\n"); on = 1; } cattext(&out,"\n@item\n"); idx+=3; } else { catchar(&out, at(tos, idx)); if (on && at(tos, idx) == '\n' && at(tos, idx+1) == '\n' && at(tos, idx+2) != 'o') { cattext(&out, "@end itemize"); on = 0; } idx++; } } if (on) { cattext(&out,"@end itemize\n"); } delete_string(tos); *tos = out; pc++; }/* Turn <<foo>> into @code{foo} in place at TOS*/ WORD(do_fancy_stuff){ unsigned int idx = 0; string_type out; init_string(&out); while (at(tos, idx)) { if (at(tos, idx) == '<' && at(tos, idx+1) == '<' && !isspace(at(tos,idx + 2))) { /* This qualifies as a << startup */ idx +=2; cattext(&out,"@code{"); while(at(tos,idx) && at(tos,idx) != '>' ) { catchar(&out, at(tos, idx)); idx++; } cattext(&out,"}");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -