--- stack/stack.c 2002/02/17 04:03:57 1.89 +++ stack/stack.c 2002/03/07 03:28:29 1.91 @@ -1,3 +1,25 @@ +/* + stack - an interactive interpreter for a stack-based language + Copyright (C) 2002 Mats Alritzson and Teddy Hogeborn + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Authors: Mats Alritzson + Teddy Hogeborn +*/ + /* printf, sscanf, fgets, fprintf, fopen, perror */ #include /* exit, EXIT_SUCCESS, malloc, free */ @@ -8,12 +30,16 @@ #include /* strcmp, strcpy, strlen, strcat, strdup */ #include -/* getopt, STDIN_FILENO, STDOUT_FILENO */ +/* getopt, STDIN_FILENO, STDOUT_FILENO, usleep */ #include /* EX_NOINPUT, EX_USAGE */ #include /* mtrace, muntrace */ #include +/* ioctl */ +#include +/* KDMKTONE */ +#include #include "stack.h" @@ -24,6 +50,8 @@ env->gc_limit= 20; env->gc_count= 0; + env->gc_ref= NULL; + env->gc_protect= NULL; env->head= NULL; for(i= 0; ihead)==NULL) { printerr("Too Few Arguments"); - env->err=1; + env->err= 1; return; } env->head= env->head->next; /* Remove the top stack item */ free(temp); /* Free the old top stack item */ + + gc_init(env); } /* Returns a pointer to a pointer to an element in the hash table. */ @@ -88,12 +118,16 @@ stackitem *nitem= malloc(sizeof(stackitem)); nval->content.ptr= NULL; + protect(env, nval); + + gc_init(env); nitem->item= nval; nitem->next= env->gc_ref; env->gc_ref= nitem; env->gc_count++; + unprotect(env); return nval; } @@ -130,6 +164,12 @@ } /* Mark */ + iterator= env->gc_protect; + while(iterator!=NULL) { + gc_mark(iterator->item); + iterator= iterator->next; + } + iterator= env->head; while(iterator!=NULL) { gc_mark(iterator->item); @@ -148,6 +188,7 @@ /* Sweep */ while(env->gc_ref!=NULL) { + if(env->gc_ref->item->gc_garb) { switch(env->gc_ref->item->type) { case string: @@ -182,6 +223,21 @@ env->gc_ref= new_head; } +void protect(environment *env, value *val) +{ + stackitem *new_item= malloc(sizeof(stackitem)); + new_item->item= val; + new_item->next= env->gc_protect; + env->gc_protect= new_item; +} + +void unprotect(environment *env) +{ + stackitem *temp= env->gc_protect; + env->gc_protect= env->gc_protect->next; + free(temp); +} + /* Push a value onto the stack */ void push_val(environment *env, value *val) { @@ -216,20 +272,19 @@ /* Mangle a symbol name to a valid C identifier name */ char *mangle_str(const char *old_string){ - char validchars[] - ="0123456789abcdef"; + char validchars[]= "0123456789abcdef"; char *new_string, *current; - new_string=malloc((strlen(old_string)*2)+4); + new_string= malloc((strlen(old_string)*2)+4); strcpy(new_string, "sx_"); /* Stack eXternal */ - current=new_string+3; + current= new_string+3; while(old_string[0] != '\0'){ - current[0]=validchars[(unsigned char)(old_string[0])/16]; - current[1]=validchars[(unsigned char)(old_string[0])%16]; - current+=2; + current[0]= validchars[(unsigned char)(old_string[0])/16]; + current[1]= validchars[(unsigned char)(old_string[0])%16]; + current+= 2; old_string++; } - current[0]='\0'; + current[0]= '\0'; return new_string; /* The caller must free() it */ } @@ -239,13 +294,13 @@ if((env->head)==NULL) { printerr("Too Few Arguments"); - env->err=1; + env->err= 1; return; } if(env->head->item->type!=string) { printerr("Bad Argument Type"); - env->err=2; + env->err= 2; return; } @@ -298,18 +353,18 @@ if(handle==NULL) /* If no handle */ handle= dlopen(NULL, RTLD_LAZY); - mangled=mangle_str(in_string); /* mangle the name */ + mangled= mangle_str(in_string); /* mangle the name */ funcptr= dlsym(handle, mangled); /* and try to find it */ free(mangled); - dlerr=dlerror(); + dlerr= dlerror(); if(dlerr != NULL) { /* If no function was found */ funcptr= dlsym(handle, in_string); /* Get function pointer */ - dlerr=dlerror(); + dlerr= dlerror(); } if(dlerr==NULL) { /* If a function was found */ new_fvalue= new_val(env); /* Create a new value */ - new_fvalue->type=func; /* The new value is a function pointer */ - new_fvalue->content.ptr=funcptr; /* Store function pointer */ + new_fvalue->type= func; /* The new value is a function pointer */ + new_fvalue->content.ptr= funcptr; /* Store function pointer */ (*new_symbol)->val= new_fvalue; /* Bind the symbol to the new function value */ } @@ -497,9 +552,11 @@ env->err=3; return; } + protect(env, val); toss(env); /* toss the symbol */ if(env->err) return; push_val(env, val); /* Return its bound value */ + unprotect(env); } /* If the top element is a symbol, determine if it's bound to a @@ -539,15 +596,20 @@ /* If it's a list */ case list: temp_val= env->head->item; + protect(env, temp_val); toss(env); if(env->err) return; iterator= (stackitem*)temp_val->content.ptr; + unprotect(env); + while(iterator!=NULL) { push_val(env, iterator->item); + if(env->head->item->type==symb && strcmp(";", ((symbol*)(env->head->item->content.ptr))->id)==0) { toss(env); if(env->err) return; + if(iterator->next == NULL){ goto eval_start; } @@ -569,25 +631,25 @@ if((env->head)==NULL) { printerr("Too Few Arguments"); - env->err=1; + env->err= 1; return; } if(env->head->item->type!=list) { printerr("Bad Argument Type"); - env->err=2; + env->err= 2; return; } - old_head=(stackitem *)(env->head->item->content.ptr); - new_head=NULL; + old_head= (stackitem *)(env->head->item->content.ptr); + new_head= NULL; while(old_head != NULL){ - item=old_head; - old_head=old_head->next; - item->next=new_head; - new_head=item; + item= old_head; + old_head= old_head->next; + item->next= new_head; + new_head= item; } - env->head->item->content.ptr=new_head; + env->head->item->content.ptr= new_head; } /* Make a list. */ @@ -636,12 +698,12 @@ /* Is top element a list? */ if(env->head==NULL) { printerr("Too Few Arguments"); - env->err=1; + env->err= 1; return; } if(env->head->item->type!=list) { printerr("Bad Argument Type"); - env->err=2; + env->err= 2; return; } @@ -673,7 +735,7 @@ if((env->head)==NULL || env->head->next==NULL) { printerr("Too Few Arguments"); - env->err=1; + env->err= 1; return; } @@ -693,13 +755,13 @@ if((env->head)==NULL) { printerr("Too Few Arguments"); - env->err=1; + env->err= 1; return; } if(env->head->item->type!=integer) { printerr("Bad Argument Type"); - env->err=2; + env->err= 2; return; } @@ -724,20 +786,18 @@ /* Needs two values on the stack, the top one must be a symbol */ if(env->head==NULL || env->head->next==NULL) { printerr("Too Few Arguments"); - env->err=1; + env->err= 1; return; } if(env->head->item->type!=symb) { printerr("Bad Argument Type"); - env->err=2; + env->err= 2; return; } /* long names are a pain */ - sym=env->head->item->content.ptr; - - /* if the symbol was bound to something else, throw it away */ + sym= env->head->item->content.ptr; /* Bind the symbol to the value */ sym->val= env->head->next->item; @@ -760,6 +820,7 @@ env->symbols[i]= NULL; } + env->gc_limit= 0; gc_init(env); if(env->free_string!=NULL) @@ -868,6 +929,14 @@ } } + if(myenv.interactive) { + printf("Stack version $Revision: 1.91 $\n\ +Copyright (C) 2002 Mats Alritzson and Teddy Hogeborn\n\ +Stack comes with ABSOLUTELY NO WARRANTY; for details type `warranty;'.\n\ +This is free software, and you are welcome to redistribute it\n\ +under certain conditions; type `copying;' for details.\n"); + } + while(1) { if(myenv.in_string==NULL) { if (myenv.interactive) { @@ -882,7 +951,7 @@ } sx_72656164(&myenv); if (myenv.err==4) { - return EX_NOINPUT; + return EXIT_SUCCESS; /* EOF */ } else if(myenv.head!=NULL && myenv.head->item->type==symb && ((symbol*)(myenv.head->item->content.ptr))->id[0]==';') { @@ -904,7 +973,7 @@ if((env->head)==NULL || env->head->next==NULL) { printerr("Too Few Arguments"); - env->err=1; + env->err= 1; return; } @@ -912,6 +981,7 @@ && env->head->next->item->type==string) { a_val= env->head->item; b_val= env->head->next->item; + protect(env, a_val); protect(env, b_val); toss(env); if(env->err) return; toss(env); if(env->err) return; len= strlen(a_val->content.ptr)+strlen(b_val->content.ptr)+1; @@ -919,6 +989,7 @@ strcpy(new_string, b_val->content.ptr); strcat(new_string, a_val->content.ptr); push_cstring(env, new_string); + unprotect(env); unprotect(env); free(new_string); return; } @@ -929,10 +1000,10 @@ env->err=2; return; } - a=env->head->item->content.val; + a= env->head->item->content.val; toss(env); if(env->err) return; - b=env->head->item->content.val; + b= env->head->item->content.val; toss(env); if(env->err) return; push_int(env, a+b); } @@ -953,6 +1024,7 @@ env->err=2; return; } + a=env->head->item->content.val; toss(env); if(env->err) return; b=env->head->item->content.val; @@ -976,6 +1048,7 @@ env->err=2; return; } + a=env->head->item->content.val; toss(env); if(env->err) return; b=env->head->item->content.val; @@ -987,42 +1060,46 @@ value *copy_val(environment *env, value *old_value){ stackitem *old_item, *new_item, *prev_item; - value *new_value=new_val(env); + value *new_value= new_val(env); - new_value->type=old_value->type; + protect(env, old_value); + new_value->type= old_value->type; switch(old_value->type){ case integer: - new_value->content.val=old_value->content.val; + new_value->content.val= old_value->content.val; break; case string: - (char *)(new_value->content.ptr) - = strdup((char *)(old_value->content.ptr)); + (char *)(new_value->content.ptr)= + strdup((char *)(old_value->content.ptr)); break; case func: case symb: - new_value->content.ptr=old_value->content.ptr; + new_value->content.ptr= old_value->content.ptr; break; case list: - new_value->content.ptr=NULL; + new_value->content.ptr= NULL; - prev_item=NULL; - old_item=(stackitem *)(old_value->content.ptr); + prev_item= NULL; + old_item= (stackitem*)(old_value->content.ptr); while(old_item != NULL) { /* While list is not empty */ new_item= malloc(sizeof(stackitem)); - new_item->item=copy_val(env, old_item->item); /* recurse */ - new_item->next=NULL; + new_item->item= copy_val(env, old_item->item); /* recurse */ + new_item->next= NULL; if(prev_item != NULL) /* If this wasn't the first item */ - prev_item->next=new_item; /* point the previous item to the + prev_item->next= new_item; /* point the previous item to the new item */ else - new_value->content.ptr=new_item; - old_item=old_item->next; - prev_item=new_item; + new_value->content.ptr= new_item; + old_item= old_item->next; + prev_item= new_item; } break; } + + unprotect(env); + return new_value; } @@ -1030,7 +1107,7 @@ extern void sx_647570(environment *env) { if((env->head)==NULL) { printerr("Too Few Arguments"); - env->err=1; + env->err= 1; return; } push_val(env, copy_val(env, env->head->item)); @@ -1043,7 +1120,7 @@ if((env->head)==NULL || env->head->next==NULL) { printerr("Too Few Arguments"); - env->err=1; + env->err= 1; return; } @@ -1116,9 +1193,11 @@ } loop= env->head->item; + protect(env, loop); toss(env); if(env->err) return; test= env->head->item; + protect(env, test); toss(env); if(env->err) return; do { @@ -1127,7 +1206,7 @@ if(env->head->item->type != integer) { printerr("Bad Argument Type"); - env->err=2; + env->err= 2; return; } @@ -1142,6 +1221,8 @@ } } while(truth); + + unprotect(env); unprotect(env); } @@ -1165,6 +1246,7 @@ } loop= env->head->item; + protect(env, loop); toss(env); if(env->err) return; foo2= env->head->item->content.val; @@ -1188,6 +1270,7 @@ foo1--; } } + unprotect(env); } /* Variant of for-loop */ @@ -1198,20 +1281,22 @@ if((env->head)==NULL || env->head->next==NULL) { printerr("Too Few Arguments"); - env->err=1; + env->err= 1; return; } if(env->head->next->item->type != list) { printerr("Bad Argument Type"); - env->err=2; + env->err= 2; return; } loop= env->head->item; + protect(env, loop); toss(env); if(env->err) return; foo= env->head->item; + protect(env, foo); toss(env); if(env->err) return; iterator= foo->content.ptr; @@ -1222,6 +1307,7 @@ eval(env); if(env->err) return; iterator= iterator->next; } + unprotect(env); unprotect(env); } /* "to" */ @@ -1282,9 +1368,9 @@ const char strform[]= "\"%[^\"]\"%n"; const char intform[]= "%i%n"; const char blankform[]= "%*[ \t]%n"; - const char ebrackform[]= "%*1[]]%n"; - const char semicform[]= "%*1[;]%n"; - const char bbrackform[]= "%*1[[]%n"; + const char ebrackform[]= "]%n"; + const char semicform[]= ";%n"; + const char bbrackform[]= "[%n"; int itemp, readlength= -1; static int depth= 0; @@ -1347,3 +1433,352 @@ if(depth) return sx_72656164(env); } + +extern void beep(environment *env) { + + int freq, dur, period, ticks; + + if((env->head)==NULL || env->head->next==NULL) { + printerr("Too Few Arguments"); + env->err=1; + return; + } + + if(env->head->item->type!=integer + || env->head->next->item->type!=integer) { + printerr("Bad Argument Type"); + env->err=2; + return; + } + + dur=env->head->item->content.val; + toss(env); + freq=env->head->item->content.val; + toss(env); + + period=1193180/freq; /* convert freq from Hz to period + length */ + ticks=dur*.001193180; /* convert duration from µseconds to + timer ticks */ + +/* ticks=dur/1000; */ + + /* if (ioctl(STDOUT_FILENO, KDMKTONE, (125<<16) + 0x637)==0) */ + switch (ioctl(STDOUT_FILENO, KDMKTONE, (ticks<<16) | period)){ + case 0: + usleep(dur); + return; + case -1: + perror("beep"); + env->err=5; + return; + default: + abort(); + } +}; + +/* "wait" */ +extern void sx_77616974(environment *env) { + + int dur; + + if((env->head)==NULL) { + printerr("Too Few Arguments"); + env->err=1; + return; + } + + if(env->head->item->type!=integer) { + printerr("Bad Argument Type"); + env->err=2; + return; + } + + dur=env->head->item->content.val; + toss(env); + + usleep(dur); +}; + +extern void copying(environment *env){ + printf("GNU GENERAL PUBLIC LICENSE\n\ + Version 2, June 1991\n\ +\n\ + Copyright (C) 1989, 1991 Free Software Foundation, Inc.\n\ + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\n\ + Everyone is permitted to copy and distribute verbatim copies\n\ + of this license document, but changing it is not allowed.\n\ +\n\ + Preamble\n\ +\n\ + The licenses for most software are designed to take away your\n\ +freedom to share and change it. By contrast, the GNU General Public\n\ +License is intended to guarantee your freedom to share and change free\n\ +software--to make sure the software is free for all its users. This\n\ +General Public License applies to most of the Free Software\n\ +Foundation's software and to any other program whose authors commit to\n\ +using it. (Some other Free Software Foundation software is covered by\n\ +the GNU Library General Public License instead.) You can apply it to\n\ +your programs, too.\n\ +\n\ + When we speak of free software, we are referring to freedom, not\n\ +price. Our General Public Licenses are designed to make sure that you\n\ +have the freedom to distribute copies of free software (and charge for\n\ +this service if you wish), that you receive source code or can get it\n\ +if you want it, that you can change the software or use pieces of it\n\ +in new free programs; and that you know you can do these things.\n\ +\n\ + To protect your rights, we need to make restrictions that forbid\n\ +anyone to deny you these rights or to ask you to surrender the rights.\n\ +These restrictions translate to certain responsibilities for you if you\n\ +distribute copies of the software, or if you modify it.\n\ +\n\ + For example, if you distribute copies of such a program, whether\n\ +gratis or for a fee, you must give the recipients all the rights that\n\ +you have. You must make sure that they, too, receive or can get the\n\ +source code. And you must show them these terms so they know their\n\ +rights.\n\ +\n\ + We protect your rights with two steps: (1) copyright the software, and\n\ +(2) offer you this license which gives you legal permission to copy,\n\ +distribute and/or modify the software.\n\ +\n\ + Also, for each author's protection and ours, we want to make certain\n\ +that everyone understands that there is no warranty for this free\n\ +software. If the software is modified by someone else and passed on, we\n\ +want its recipients to know that what they have is not the original, so\n\ +that any problems introduced by others will not reflect on the original\n\ +authors' reputations.\n\ +\n\ + Finally, any free program is threatened constantly by software\n\ +patents. We wish to avoid the danger that redistributors of a free\n\ +program will individually obtain patent licenses, in effect making the\n\ +program proprietary. To prevent this, we have made it clear that any\n\ +patent must be licensed for everyone's free use or not licensed at all.\n\ +\n\ + The precise terms and conditions for copying, distribution and\n\ +modification follow.\n\ +\n\ + GNU GENERAL PUBLIC LICENSE\n\ + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\n\ +\n\ + 0. This License applies to any program or other work which contains\n\ +a notice placed by the copyright holder saying it may be distributed\n\ +under the terms of this General Public License. The \"Program\", below,\n\ +refers to any such program or work, and a \"work based on the Program\"\n\ +means either the Program or any derivative work under copyright law:\n\ +that is to say, a work containing the Program or a portion of it,\n\ +either verbatim or with modifications and/or translated into another\n\ +language. (Hereinafter, translation is included without limitation in\n\ +the term \"modification\".) Each licensee is addressed as \"you\".\n\ +\n\ +Activities other than copying, distribution and modification are not\n\ +covered by this License; they are outside its scope. The act of\n\ +running the Program is not restricted, and the output from the Program\n\ +is covered only if its contents constitute a work based on the\n\ +Program (independent of having been made by running the Program).\n\ +Whether that is true depends on what the Program does.\n\ +\n\ + 1. You may copy and distribute verbatim copies of the Program's\n\ +source code as you receive it, in any medium, provided that you\n\ +conspicuously and appropriately publish on each copy an appropriate\n\ +copyright notice and disclaimer of warranty; keep intact all the\n\ +notices that refer to this License and to the absence of any warranty;\n\ +and give any other recipients of the Program a copy of this License\n\ +along with the Program.\n\ +\n\ +You may charge a fee for the physical act of transferring a copy, and\n\ +you may at your option offer warranty protection in exchange for a fee.\n\ +\n\ + 2. You may modify your copy or copies of the Program or any portion\n\ +of it, thus forming a work based on the Program, and copy and\n\ +distribute such modifications or work under the terms of Section 1\n\ +above, provided that you also meet all of these conditions:\n\ +\n\ + a) You must cause the modified files to carry prominent notices\n\ + stating that you changed the files and the date of any change.\n\ +\n\ + b) You must cause any work that you distribute or publish, that in\n\ + whole or in part contains or is derived from the Program or any\n\ + part thereof, to be licensed as a whole at no charge to all third\n\ + parties under the terms of this License.\n\ +\n\ + c) If the modified program normally reads commands interactively\n\ + when run, you must cause it, when started running for such\n\ + interactive use in the most ordinary way, to print or display an\n\ + announcement including an appropriate copyright notice and a\n\ + notice that there is no warranty (or else, saying that you provide\n\ + a warranty) and that users may redistribute the program under\n\ + these conditions, and telling the user how to view a copy of this\n\ + License. (Exception: if the Program itself is interactive but\n\ + does not normally print such an announcement, your work based on\n\ + the Program is not required to print an announcement.)\n\ +\n\ +These requirements apply to the modified work as a whole. If\n\ +identifiable sections of that work are not derived from the Program,\n\ +and can be reasonably considered independent and separate works in\n\ +themselves, then this License, and its terms, do not apply to those\n\ +sections when you distribute them as separate works. But when you\n\ +distribute the same sections as part of a whole which is a work based\n\ +on the Program, the distribution of the whole must be on the terms of\n\ +this License, whose permissions for other licensees extend to the\n\ +entire whole, and thus to each and every part regardless of who wrote it.\n\ +\n\ +Thus, it is not the intent of this section to claim rights or contest\n\ +your rights to work written entirely by you; rather, the intent is to\n\ +exercise the right to control the distribution of derivative or\n\ +collective works based on the Program.\n\ +\n\ +In addition, mere aggregation of another work not based on the Program\n\ +with the Program (or with a work based on the Program) on a volume of\n\ +a storage or distribution medium does not bring the other work under\n\ +the scope of this License.\n\ +\n\ + 3. You may copy and distribute the Program (or a work based on it,\n\ +under Section 2) in object code or executable form under the terms of\n\ +Sections 1 and 2 above provided that you also do one of the following:\n\ +\n\ + a) Accompany it with the complete corresponding machine-readable\n\ + source code, which must be distributed under the terms of Sections\n\ + 1 and 2 above on a medium customarily used for software interchange; or,\n\ +\n\ + b) Accompany it with a written offer, valid for at least three\n\ + years, to give any third party, for a charge no more than your\n\ + cost of physically performing source distribution, a complete\n\ + machine-readable copy of the corresponding source code, to be\n\ + distributed under the terms of Sections 1 and 2 above on a medium\n\ + customarily used for software interchange; or,\n\ +\n\ + c) Accompany it with the information you received as to the offer\n\ + to distribute corresponding source code. (This alternative is\n\ + allowed only for noncommercial distribution and only if you\n\ + received the program in object code or executable form with such\n\ + an offer, in accord with Subsection b above.)\n\ +\n\ +The source code for a work means the preferred form of the work for\n\ +making modifications to it. For an executable work, complete source\n\ +code means all the source code for all modules it contains, plus any\n\ +associated interface definition files, plus the scripts used to\n\ +control compilation and installation of the executable. However, as a\n\ +special exception, the source code distributed need not include\n\ +anything that is normally distributed (in either source or binary\n\ +form) with the major components (compiler, kernel, and so on) of the\n\ +operating system on which the executable runs, unless that component\n\ +itself accompanies the executable.\n\ +\n\ +If distribution of executable or object code is made by offering\n\ +access to copy from a designated place, then offering equivalent\n\ +access to copy the source code from the same place counts as\n\ +distribution of the source code, even though third parties are not\n\ +compelled to copy the source along with the object code.\n\ +\n\ + 4. You may not copy, modify, sublicense, or distribute the Program\n\ +except as expressly provided under this License. Any attempt\n\ +otherwise to copy, modify, sublicense or distribute the Program is\n\ +void, and will automatically terminate your rights under this License.\n\ +However, parties who have received copies, or rights, from you under\n\ +this License will not have their licenses terminated so long as such\n\ +parties remain in full compliance.\n\ +\n\ + 5. You are not required to accept this License, since you have not\n\ +signed it. However, nothing else grants you permission to modify or\n\ +distribute the Program or its derivative works. These actions are\n\ +prohibited by law if you do not accept this License. Therefore, by\n\ +modifying or distributing the Program (or any work based on the\n\ +Program), you indicate your acceptance of this License to do so, and\n\ +all its terms and conditions for copying, distributing or modifying\n\ +the Program or works based on it.\n\ +\n\ + 6. Each time you redistribute the Program (or any work based on the\n\ +Program), the recipient automatically receives a license from the\n\ +original licensor to copy, distribute or modify the Program subject to\n\ +these terms and conditions. You may not impose any further\n\ +restrictions on the recipients' exercise of the rights granted herein.\n\ +You are not responsible for enforcing compliance by third parties to\n\ +this License.\n\ +\n\ + 7. If, as a consequence of a court judgment or allegation of patent\n\ +infringement or for any other reason (not limited to patent issues),\n\ +conditions are imposed on you (whether by court order, agreement or\n\ +otherwise) that contradict the conditions of this License, they do not\n\ +excuse you from the conditions of this License. If you cannot\n\ +distribute so as to satisfy simultaneously your obligations under this\n\ +License and any other pertinent obligations, then as a consequence you\n\ +may not distribute the Program at all. For example, if a patent\n\ +license would not permit royalty-free redistribution of the Program by\n\ +all those who receive copies directly or indirectly through you, then\n\ +the only way you could satisfy both it and this License would be to\n\ +refrain entirely from distribution of the Program.\n\ +\n\ +If any portion of this section is held invalid or unenforceable under\n\ +any particular circumstance, the balance of the section is intended to\n\ +apply and the section as a whole is intended to apply in other\n\ +circumstances.\n\ +\n\ +It is not the purpose of this section to induce you to infringe any\n\ +patents or other property right claims or to contest validity of any\n\ +such claims; this section has the sole purpose of protecting the\n\ +integrity of the free software distribution system, which is\n\ +implemented by public license practices. Many people have made\n\ +generous contributions to the wide range of software distributed\n\ +through that system in reliance on consistent application of that\n\ +system; it is up to the author/donor to decide if he or she is willing\n\ +to distribute software through any other system and a licensee cannot\n\ +impose that choice.\n\ +\n\ +This section is intended to make thoroughly clear what is believed to\n\ +be a consequence of the rest of this License.\n\ +\n\ + 8. If the distribution and/or use of the Program is restricted in\n\ +certain countries either by patents or by copyrighted interfaces, the\n\ +original copyright holder who places the Program under this License\n\ +may add an explicit geographical distribution limitation excluding\n\ +those countries, so that distribution is permitted only in or among\n\ +countries not thus excluded. In such case, this License incorporates\n\ +the limitation as if written in the body of this License.\n\ +\n\ + 9. The Free Software Foundation may publish revised and/or new versions\n\ +of the General Public License from time to time. Such new versions will\n\ +be similar in spirit to the present version, but may differ in detail to\n\ +address new problems or concerns.\n\ +\n\ +Each version is given a distinguishing version number. If the Program\n\ +specifies a version number of this License which applies to it and \"any\n\ +later version\", you have the option of following the terms and conditions\n\ +either of that version or of any later version published by the Free\n\ +Software Foundation. If the Program does not specify a version number of\n\ +this License, you may choose any version ever published by the Free Software\n\ +Foundation.\n\ +\n\ + 10. If you wish to incorporate parts of the Program into other free\n\ +programs whose distribution conditions are different, write to the author\n\ +to ask for permission. For software which is copyrighted by the Free\n\ +Software Foundation, write to the Free Software Foundation; we sometimes\n\ +make exceptions for this. Our decision will be guided by the two goals\n\ +of preserving the free status of all derivatives of our free software and\n\ +of promoting the sharing and reuse of software generally.\n"); +} + +extern void warranty(environment *env){ + printf(" NO WARRANTY\n\ +\n\ + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY\n\ +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN\n\ +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES\n\ +PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED\n\ +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n\ +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS\n\ +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE\n\ +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,\n\ +REPAIR OR CORRECTION.\n\ +\n\ + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\n\ +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR\n\ +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,\n\ +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING\n\ +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED\n\ +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY\n\ +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER\n\ +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE\n\ +POSSIBILITY OF SUCH DAMAGES.\n"); +}