📄 megahal.c
字号:
exithal(); break; case SAVE: save_model("megahal.brn", model); break; case DELAY: typing_delay=!typing_delay; printf("MegaHAL typing is now %s.\n", typing_delay?"on":"off"); return 1; case SPEECH: speech=!speech; printf("MegaHAL speech is now %s.\n", speech?"on":"off"); return 1; case HELP: help(); return 1; case VOICELIST: listvoices(); return 1; case VOICE: changevoice(words, position); return 1; case BRAIN: change_personality(words, position, &model); make_greeting(greets); output=generate_reply(model, greets); write_output(output); return 1; case QUIET: quiet=!quiet; return 1; default: return 0; } return 0;}/* megahal_cleanup -- Clean up everything. Prepare for exit. */void megahal_cleanup(void){ save_model("megahal.brn", model);#ifdef AMIGA CloseLocale(_AmigaLocale);#endif}/*---------------------------------------------------------------------------*//* * Function: Execute_Command * * Purpose: Detect whether the user has typed a command, and * execute the corresponding function. */COMMAND_WORDS execute_command(DICTIONARY *words, int *position){ register unsigned int i; register unsigned int j; /* * If there is only one word, then it can't be a command. */ *position=words->size+1; if(words->size<=1) return(UNKNOWN); /* * Search through the word array. If a command prefix is found, * then try to match the following word with a command word. If * a match is found, then return a command identifier. If the * Following word is a number, then change the judge. Otherwise, * continue the search. */ for(i=0; i<words->size-1; ++i) /* * The command prefix was found. */ if(words->entry[i].word[words->entry[i].length - 1] == '#') { /* * Look for a command word. */ for(j = 0; j < COMMAND_SIZE; ++j) if(wordcmp(command[j].word, words->entry[i + 1]) == 0) { *position = i + 1; return(command[j].command); } } return(UNKNOWN);}/*---------------------------------------------------------------------------*//* * Function: ExitHAL * * Purpose: Terminate the program. */void exithal(void){#ifdef __mac_os /* * Must be called because it does use some system memory */ if (gSpeechChannel) { StopSpeech(gSpeechChannel); DisposeSpeechChannel(gSpeechChannel); gSpeechChannel = nil; }#endif exit(0);}/*---------------------------------------------------------------------------*//* * Function: Read_Input * * Purpose: Read an input string from the user. */char *read_input(char *prompt){ static char *input=NULL; bool finish; int length; int c; /* * Perform some initializations. The finish boolean variable is used * to detect a double line-feed, while length contains the number of * characters in the input string. */ finish=FALSE; length=0; if(input==NULL) { input=(char *)malloc(sizeof(char)); if(input==NULL) { error("read_input", "Unable to allocate the input string"); return(input); } } /* * Display the prompt to the user. */ fprintf(stdout, prompt); fflush(stdout); /* * Loop forever, reading characters and putting them into the input * string. */ while(TRUE) { /* * Read a single character from stdin. */ c=getc(stdin); /* * If the character is a line-feed, then set the finish variable * to TRUE. If it already is TRUE, then this is a double line-feed, * in which case we should exit. After a line-feed, display the * prompt again, and set the character to the space character, as * we don't permit linefeeds to appear in the input. */ if((char)(c)=='\n') { if(finish==TRUE) break; fprintf(stdout, prompt); fflush(stdout); finish=TRUE; c=32; } else { finish=FALSE; } /* * Re-allocate the input string so that it can hold one more * character. */ ++length; input=(char *)realloc((char *)input,sizeof(char)*(length+1)); if(input==NULL) { error("read_input", "Unable to re-allocate the input string"); return(NULL); } /* * Add the character just read to the input string. */ input[length-1]=(char)c; input[length]='\0'; } while(isspace(input[length-1])) --length; input[length]='\0'; /* * We have finished, so return the input string. */ return(input);}/*---------------------------------------------------------------------------*//* * Function: Initialize_Error * * Purpose: Close the current error file pointer, and open a new one. */bool initialize_error(char *filename){ if(errorfp!=stderr) fclose(errorfp); if(filename==NULL) return(TRUE); errorfp = fopen(filename, "a"); if(errorfp==NULL) { errorfp=stderr; return(FALSE); } return(print_header(errorfp));}/*---------------------------------------------------------------------------*//* * Function: Error * * Purpose: Print the specified message to the error file. */void error(char *title, char *fmt, ...){ va_list argp; fprintf(errorfp, "%s: ", title); va_start(argp, fmt); vfprintf(errorfp, fmt, argp); va_end(argp); fprintf(errorfp, ".\n"); fflush(errorfp); fprintf(stderr, "MegaHAL died for some reason; check the error log.\n"); exit(1);}/*---------------------------------------------------------------------------*/bool warn(char *title, char *fmt, ...){ va_list argp; fprintf(errorfp, "%s: ", title); va_start(argp, fmt); vfprintf(errorfp, fmt, argp); va_end(argp); fprintf(errorfp, ".\n"); fflush(errorfp); fprintf(stderr, "MegaHAL emitted a warning; check the error log.\n"); return(TRUE);}/*---------------------------------------------------------------------------*//* * Function: Initialize_Status * * Purpose: Close the current status file pointer, and open a new one. */bool initialize_status(char *filename){ if(statusfp!=stdout) fclose(statusfp); if(filename==NULL) return(FALSE); statusfp=fopen(filename, "a"); if(statusfp==NULL) { statusfp=stdout; return(FALSE); } return(print_header(statusfp));}/*---------------------------------------------------------------------------*//* * Function: Status * * Purpose: Print the specified message to the status file. */bool status(char *fmt, ...){ va_list argp; va_start(argp, fmt); vfprintf(statusfp, fmt, argp); va_end(argp); fflush(statusfp); return(TRUE);}/*---------------------------------------------------------------------------*//* * Function: Print_Header * * Purpose: Display a copyright message and timestamp. */bool print_header(FILE *file){ time_t clock; char timestamp[1024]; struct tm *local; clock=time(NULL); local=localtime(&clock); strftime(timestamp, 1024, "Start at: [%Y/%m/%d %H:%M:%S]\n", local); fprintf(file, "MegaHALv8\n"); fprintf(file, "Copyright (C) 1998 Jason Hutchens\n"); fprintf(file, timestamp); fflush(file); return(TRUE);}/*---------------------------------------------------------------------------*//* * Function: Write_Output * * Purpose: Display the output string. */void write_output(char *output){ char *formatted; char *bit; capitalize(output); speak(output); width=75; formatted=format_output(output); delay(formatted); width=64; formatted=format_output(output); bit=strtok(formatted, "\n"); if(bit==NULL) (void)status("MegaHAL: %s\n", formatted); while(bit!=NULL) { (void)status("MegaHAL: %s\n", bit); bit=strtok(NULL, "\n"); }}/*---------------------------------------------------------------------------*//* * Function: Capitalize * * Purpose: Convert a string to look nice. */void capitalize(char *string){ register unsigned int i; bool start=TRUE; for(i=0; i<strlen(string); ++i) { if(isalpha(string[i])) { if(start==TRUE) string[i]=(char)toupper((int)string[i]); else string[i]=(char)tolower((int)string[i]); start=FALSE; } if((i>2)&&(strchr("!.?", string[i-1])!=NULL)&&(isspace(string[i]))) start=TRUE; }}/*---------------------------------------------------------------------------*//* * Function: Upper * * Purpose: Convert a string to its uppercase representation. */void upper(char *string){ register unsigned int i; for(i=0; i<strlen(string); ++i) string[i]=(char)toupper((int)string[i]);}/*---------------------------------------------------------------------------*//* * Function: Write_Input * * Purpose: Log the user's input */void write_input(char *input){ char *formatted; char *bit; width=64; formatted=format_output(input); bit=strtok(formatted, "\n"); if(bit==NULL) (void)status("User: %s\n", formatted); while(bit!=NULL) { (void)status("User: %s\n", bit); bit=strtok(NULL, "\n"); }}/*---------------------------------------------------------------------------*//* * Function: Format_Output * * Purpose: Format a string to display nicely on a terminal of a given * width. */static char *format_output(char *output){ static char *formatted=NULL; register unsigned int i,j,c; int l; if(formatted==NULL) { formatted=(char *)malloc(sizeof(char)); if(formatted==NULL) { error("format_output", "Unable to allocate formatted"); return("ERROR"); } } formatted=(char *)realloc((char *)formatted, sizeof(char)*(strlen(output)+2)); if(formatted==NULL) { error("format_output", "Unable to re-allocate formatted"); return("ERROR"); } l=0; j=0; for(i=0; i<strlen(output); ++i) { if((l==0)&&(isspace(output[i]))) continue; formatted[j]=output[i]; ++j; ++l; if(!nowrap) if(l>=width) for(c=j-1; c>0; --c) if(formatted[c]==' ') { formatted[c]='\n'; l=j-c-1; break; } } if((j>0)&&(formatted[j-1]!='\n')) { formatted[j]='\n'; ++j; } formatted[j]='\0'; return(formatted);}/*---------------------------------------------------------------------------*//* * Function: Add_Word * * Purpose: Add a word to a dictionary, and return the identifier * assigned to the word. If the word already exists in * the dictionary, then return its current identifier * without adding it again. */BYTE2 add_word(DICTIONARY *dictionary, STRING word){ register int i; int position; bool found; /* * If the word's already in the dictionary, there is no need to add it */ position=search_dictionary(dictionary, word, &found); if(found==TRUE) goto succeed; /* * Increase the number of words in the dictionary */ dictionary->size+=1; /* * Allocate one more entry for the word index */ if(dictionary->index==NULL) { dictionary->index=(BYTE2 *)malloc(sizeof(BYTE2)* (dictionary->size)); } else { dictionary->index=(BYTE2 *)realloc((BYTE2 *) (dictionary->index),sizeof(BYTE2)*(dictionary->size)); } if(dictionary->index==NULL) { error("add_word", "Unable to reallocate the index."); goto fail; } /* * Allocate one more entry for the word array */ if(dictionary->entry==NULL) { dictionary->entry=(STRING *)malloc(sizeof(STRING)*(dictionary->size)); } else { dictionary->entry=(STRING *)realloc((STRING *)(dictionary->entry), sizeof(STRING)*(dictionary->size)); } if(dictionary->entry==NULL) { error("add_word", "Unable to reallocate the dictionary to %d elements.", dictionary->size); goto fail; } /* * Copy the new word into the word array */ dictionary->entry[dictionary->size-1].length=word.length; dictionary->entry[dictionary->size-1].word=(char *)malloc(sizeof(char)* (word.length)); if(dictionary->entry[dictionary->size-1].word==NULL) { error("add_word", "Unable to allocate the word."); goto fail; } for(i=0; i<word.length; ++i) dictionary->entry[dictionary->size-1].word[i]=word.word[i]; /* * Shuffle the word index to keep it sorted alphabetically */ for(i=(dictionary->size-1); i>position; --i) dictionary->index[i]=dictionary->index[i-1]; /* * Copy the new symbol identifier into the word index
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -