progress progress_load(levelset *set, char *user) { FILE *fp; char buf[FILENAME_MAX+10]; char fname[FILENAME_MAX]; progress p; p.levnum = 0; p.date = -1; fname[sizeof(fname)-1] = '\0'; strncpy(fname, SAVEDIR, sizeof(fname)); strncpy(fname + strlen(fname), set->name, sizeof(fname)-strlen(fname)); strncpy(fname + strlen(fname), ".", sizeof(fname)-strlen(fname)); strncpy(fname + strlen(fname), user, sizeof(fname)-strlen(fname)); strncpy(fname + strlen(fname), ".progress", sizeof(fname)-strlen(fname)); if (fname[sizeof(fname)-1] != '\0') { /* file name length overflow */ return p; } fp = fopen(fname, "r"); if (!fp) { /* unable to read progress file */ return p; } while (fgets(buf, sizeof(buf), fp)) { if (buf[strlen(buf)-1] != '\n') { /* line length overflow in save file */ return p; } buf[strcspn(buf, "\r\n")] = '\0'; if (ishdr(buf, "Level: ")) { p.levnum = atoi(buf+7); } else if (ishdr(buf, "Date: ")) { p.date = parse_date(buf+6); } else { /* unrecognised keyword in progress file */ return p; } } fclose(fp); return p; }
levelset *levelset_load(char *filename) { FILE *fp; char buf[FILENAME_MAX+10]; char fname[FILENAME_MAX]; levelset *set; fname[sizeof(fname)-1] = '\0'; strncpy(fname, LEVELDIR, sizeof(fname)); strncpy(fname + strlen(fname), filename, sizeof(fname)-strlen(fname)); strncpy(fname + strlen(fname), ".set", sizeof(fname)-strlen(fname)); if (fname[sizeof(fname)-1] != '\0') { fatal("File name length overflow"); } fp = fopen(fname, "r"); if (!fp) { fatal("Unable to read level set file"); } set = levelset_new(); set->title = NULL; set->name = filename; while (fgets(buf, sizeof(buf), fp)) { if (buf[strlen(buf)-1] != '\n') { fatal("Line length overflow in level set file"); } buf[strcspn(buf, "\r\n")] = '\0'; if (ishdr(buf, "Title: ")) { if (set->title) { fatal("Multiple titles in level set file"); } set->title = dupstr(buf + 7); } else if (ishdr(buf, "Level: ")) { levelset_nlevels(set, set->nlevels+1); set->levels[set->nlevels-1] = level_load(buf + 7); } else { fatal("Unrecognised keyword in level set file"); } } fclose(fp); return set; }
static inline int end_of_block(Line *t) { int dummy; if ( !t ) return 0; return ( (S(t->text) <= t->dle) || ishr(t) || ishdr(t, &dummy) ); }
static inline int end_of_block(Line *t, DWORD flags) { int dummy; if ( !t ) return 0; return ( (S(t->text) <= t->dle) || ishr(t, flags) || ishdr(t, &dummy, flags) ); }
static void assert2_tag_hdr_consistency( msgc_context_t *context, word w ) { #ifndef NDEBUG2 switch (tagof(w)) { case VEC_TAG: if (!(ishdr(*ptrof(w)) && header(*ptrof(w)) == header(VEC_HDR) )) { consolemsg("VEC w: 0x%08x *ptrof(w): 0x%08x ishdr: %s header(*ptrof(w)): %x", w, *ptrof(w), ishdr(*ptrof(w))?"TRUE":"FALSE", header(*ptrof(w))); } assert( ishdr(*ptrof(w)) && header(*ptrof(w)) == header(VEC_HDR) ); break; case PROC_TAG: if (!( ishdr(*ptrof(w)) && header(*ptrof(w)) == header(PROC_HDR) )) { consolemsg("PROC w: 0x%08x *ptrof(w): 0x%08x ishdr: %s header(*ptrof(w)): %x", w, *ptrof(w), ishdr(*ptrof(w))?"TRUE":"FALSE", header(*ptrof(w))); } assert( ishdr(*ptrof(w)) && header(*ptrof(w)) == header(PROC_HDR) ); break; } #endif }
static void assert2_basic_invs( msgc_context_t *context, word src, word obj ) { #ifndef NDEBUG2 word TMP = obj; if (isptr(TMP)) { gc_check_remset_invs( context->gc, src, obj ); assert2( (context)->lowest_heap_address <= ptrof(TMP) ); assert2( ptrof(TMP) < (context)->highest_heap_address ); if (! gc_is_address_mapped( context->gc, ptrof(TMP), FALSE )) { assert2(gc_is_address_mapped( context->gc, ptrof(TMP), TRUE )); } if (tagof(TMP) == PAIR_TAG) { /* no header on pairs... */ } else if (tagof(TMP) == VEC_TAG) { assert2(ishdr(*ptrof(TMP))); assert2(header(*ptrof(TMP)) == header(VEC_HDR)); } else if (tagof(TMP) == PROC_TAG) { assert2(ishdr(*ptrof(TMP))); assert2(header(*ptrof(TMP)) == header(PROC_HDR)); } } #endif }
word *los_walk_list( los_list_t *list, word *p ) { word *n; /* assert( p==0 or p is on the list ); */ if (p == 0) p = list->header; n = next( p ); if (n == list->header ) return 0; else { assert( ishdr( *n ) ); return n; } }
bool los_mark( los_t *los, los_list_t *marked, word *w, int gen_no ) { word *p = prev( w ); /* assert( w is the address of a live large object ); */ if (p == 0) return 1; /* Already marked and moved */ assert( ishdr( *w ) ); remove( w ); los->object_lists[ gen_no ]->bytes -= size( w ); /* marked->bytes += size( w ); WRONG! -- insert_at_end does this too */ insert_at_end( w, marked ); set_prev( w, 0 ); return 0; }
static int endoftextblock(Line *t, int toplevelblock, DWORD flags) { int z; if ( blankline(t)||isquote(t)||ishdr(t,&z)||ishr(t) ) return 1; /* HORRIBLE STANDARDS KLUDGE: non-toplevel paragraphs absorb adjacent * code blocks */ if ( toplevelblock && iscode(t) ) return 1; /* HORRIBLE STANDARDS KLUDGE: Toplevel paragraphs eat absorb adjacent * list items, but sublevel blocks behave properly. */ return toplevelblock ? 0 : islist(t,&z,flags, &z); }
static int islist(Line *t, int *clip, DWORD flags, int *list_type) { int i, j; char *q; if ( /*iscode(t) ||*/ blankline(t) || ishdr(t,&i) || ishr(t) ) return 0; if ( !(flags & (MKD_NODLIST|MKD_STRICT)) && isdefinition(t,clip,list_type) ) return DL; if ( strchr("*-+", T(t->text)[t->dle]) && isspace(T(t->text)[t->dle+1]) ) { i = nextnonblank(t, t->dle+1); *clip = (i > 4) ? 4 : i; *list_type = UL; return AL; } if ( (j = nextblank(t,t->dle)) > t->dle ) { if ( T(t->text)[j-1] == '.' ) { if ( !(flags & (MKD_NOALPHALIST|MKD_STRICT)) && (j == t->dle + 2) && isalpha(T(t->text)[t->dle]) ) { j = nextnonblank(t,j); *clip = (j > 4) ? 4 : j; *list_type = AL; return AL; } strtoul(T(t->text)+t->dle, &q, 10); if ( (q > T(t->text)+t->dle) && (q == T(t->text) + (j-1)) ) { j = nextnonblank(t,j); *clip = (j > 4) ? 4 : j; *list_type = OL; return AL; } } } return 0; }
static Line* is_extra_dt(Line *t, int *clip) { #if USE_EXTRA_DL int i; if ( t && t->next && T(t->text)[0] != '=' && T(t->text)[S(t->text)-1] != '=') { Line *x; if ( iscode(t) || blankline(t) || ishdr(t,&i) || ishr(t) ) return 0; if ( (x = skipempty(t->next)) && is_extra_dd(x) ) { *clip = x->dle+2; return t; } if ( x=is_extra_dt(t->next, clip) ) return x; } #endif return 0; }
/* * break a collection of markdown input into * blocks of lists, code, html, and text to * be marked up. */ static Paragraph * compile(Line *ptr, int toplevel, MMIOT *f) { ParagraphRoot d = { 0, 0 }; Paragraph *p = 0; Line *r; int para = toplevel; int blocks = 0; int hdr_type, list_type, list_class, indent; ptr = consume(ptr, ¶); while ( ptr ) { if ( iscode(ptr) ) { p = Pp(&d, ptr, CODE); if ( f->flags & MKD_1_COMPAT) { /* HORRIBLE STANDARDS KLUDGE: the first line of every block * has trailing whitespace trimmed off. */ ___mkd_tidy(&p->text->text); } ptr = codeblock(p); } #if WITH_FENCED_CODE else if ( iscodefence(ptr,3,0) && (p=fencedcodeblock(&d, &ptr)) ) /* yay, it's already done */ ; #endif else if ( ishr(ptr) ) { p = Pp(&d, 0, HR); r = ptr; ptr = ptr->next; ___mkd_freeLine(r); } else if ( list_class = islist(ptr, &indent, f->flags, &list_type) ) { if ( list_class == DL ) { p = Pp(&d, ptr, DL); ptr = definition_block(p, indent, f, list_type); } else { p = Pp(&d, ptr, list_type); ptr = enumerated_block(p, indent, f, list_class); } } else if ( isquote(ptr) ) { p = Pp(&d, ptr, QUOTE); ptr = quoteblock(p, f->flags); p->down = compile(p->text, 1, f); p->text = 0; } else if ( ishdr(ptr, &hdr_type) ) { p = Pp(&d, ptr, HDR); ptr = headerblock(p, hdr_type); } else { p = Pp(&d, ptr, MARKUP); ptr = textblock(p, toplevel, f->flags); /* tables are a special kind of paragraph */ if ( actually_a_table(f, p->text) ) p->typ = TABLE; } if ( (para||toplevel) && !p->align ) p->align = PARA; blocks++; para = toplevel || (blocks > 1); ptr = consume(ptr, ¶); if ( para && !p->align ) p->align = PARA; } return T(d); }
static level *level_load(char *filename) { FILE *fp; char buf[FILENAME_MAX+10]; char fname[FILENAME_MAX]; level *level; int nlines; fname[sizeof(fname)-1] = '\0'; strncpy(fname, LEVELDIR, sizeof(fname)); strncpy(fname + strlen(fname), filename, sizeof(fname)-strlen(fname)); if (fname[sizeof(fname)-1] != '\0') { fatal("File name length overflow"); } fp = fopen(fname, "r"); if (!fp) { fatal("Unable to read level file"); } level = level_new(); level->title = NULL; level->width = level->height = -1; nlines = 0; while (fgets(buf, sizeof(buf), fp)) { if (buf[strlen(buf)-1] != '\n') { fatal("Line length overflow in level set file"); } buf[strcspn(buf, "\r\n")] = '\0'; if (ishdr(buf, "Title: ")) { if (level->title) { fatal("Multiple titles in level file"); } level->title = dupstr(buf + 7); } else if (ishdr(buf, "Width: ")) { level->width = atoi(buf + 7); } else if (ishdr(buf, "Height: ")) { level->height = atoi(buf + 8); } else if (ishdr(buf, "Map: ")) { if (level->leveldata == NULL) { fatal("Map before size in level file"); } if ((int)strlen(buf + 5) != level->width) { fatal("Wrong length map line in level file"); } if (nlines >= level->height) { fatal("Too many map lines in level file"); } memcpy(level->leveldata + level->width * nlines, buf + 5, level->width); nlines++; } else { fatal("Unrecognised keyword in level file"); } if (level->width > 0 && level->height > 0 && level->leveldata == NULL) level_setsize(level, level->width, level->height); } if (nlines < level->height) { fatal("Not enough map lines in level file"); } fclose(fp); return level; }
gamestate *savepos_load(levelset *set, char *user, int savenum) { FILE *fp; char buf[FILENAME_MAX+10]; char fname[FILENAME_MAX]; gamestate *state; int nlines, levnum; int i, j; fname[sizeof(fname)-1] = '\0'; strncpy(fname, SAVEDIR, sizeof(fname)); strncpy(fname + strlen(fname), set->name, sizeof(fname)-strlen(fname)); strncpy(fname + strlen(fname), ".", sizeof(fname)-strlen(fname)); strncpy(fname + strlen(fname), user, sizeof(fname)-strlen(fname)); sprintf(buf, ".%d", savenum+1); strncpy(fname + strlen(fname), buf, sizeof(fname)-strlen(fname)); if (fname[sizeof(fname)-1] != '\0') { /* filename length overflow */ return NULL; } fp = fopen(fname, "r"); if (!fp) { /* can't open save file */ return NULL; } state = NULL; nlines = 0; while (fgets(buf, sizeof(buf), fp)) { if (buf[strlen(buf)-1] != '\n') { /* line length overflow in save file */ return NULL; } buf[strcspn(buf, "\r\n")] = '\0'; if (state == NULL && !ishdr(buf, "Level: ")) { /* Level: line not first in save file */ return NULL; } if (ishdr(buf, "Level: ")) { levnum = atoi(buf+7); state = gamestate_new(set->levels[levnum-1]->width, set->levels[levnum-1]->height); state->levnum = levnum; state->title = set->levels[levnum-1]->title; state->status = PLAYING; } else if (ishdr(buf, "Moves: ")) { state->movenum = atoi(buf + 7); } else if (ishdr(buf, "Gold: ")) { state->gold_got = atoi(buf + 6); } else if (ishdr(buf, "TotalGold: ")) { state->gold_total = atoi(buf + 11); } else if (ishdr(buf, "Map: ")) { if (state->leveldata == NULL) { /* map before size in save file */ return NULL; } if ((int)strlen(buf + 5) != state->width) { /* wrong length map line in save file */ return NULL; } if (nlines >= state->height) { /* too many map lines in save file */ return NULL; } memcpy(state->leveldata + state->width * nlines, buf + 5, state->width); nlines++; } else { /* unrecognised keyword in save file */ return NULL; } } if (nlines < state->height) { /* not enough map lines in save file */ return NULL; } fclose(fp); /* * Find the player. */ for (j = 0; j < state->height; j++) { for (i = 0; i < state->width; i++) { if (state->leveldata[j*state->width+i] == '@') { state->player_x = i; state->player_y = j; } } } return state; }
/* * break a collection of markdown input into * blocks of lists, code, html, and text to * be marked up. */ static Paragraph * compile(Line *ptr, int toplevel, MMIOT *f) { ParagraphRoot d = { 0, 0 }; Paragraph *p = 0; Line *r; int para = toplevel; int blocks = 0; int hdr_type, list_type, list_class, indent; ptr = consume(ptr, ¶); while ( ptr ) { if ( iscode(ptr) ) { p = Pp(&d, ptr, CODE); if ( f->flags & MKD_1_COMPAT) { /* HORRIBLE STANDARDS KLUDGE: the first line of every block * has trailing whitespace trimmed off. */ ___mkd_tidy(&p->text->text); } ptr = codeblock(p); } else if ( ishr(ptr) ) { p = Pp(&d, 0, HR); r = ptr; ptr = ptr->next; ___mkd_freeLine(r); } else if (( list_class = islist(ptr, &indent, f->flags, &list_type) )) { if ( list_class == DL ) { p = Pp(&d, ptr, DL); ptr = definition_block(p, indent, f, list_type); } else { p = Pp(&d, ptr, list_type); ptr = enumerated_block(p, indent, f, list_class); } } else if ( isquote(ptr) ) { p = Pp(&d, ptr, QUOTE); ptr = quoteblock(p, f->flags); p->down = compile(p->text, 1, f); p->text = 0; } else if ( ishdr(ptr, &hdr_type) ) { p = Pp(&d, ptr, HDR); ptr = headerblock(p, hdr_type); } else if ( istable(ptr) && !(f->flags & (MKD_STRICT|MKD_NOTABLES)) ) { p = Pp(&d, ptr, TABLE); ptr = tableblock(p); } else { p = Pp(&d, ptr, MARKUP); ptr = textblock(p, toplevel, f->flags); } if ( (para||toplevel) && !p->align ) p->align = PARA; blocks++; para = toplevel || (blocks > 1); ptr = consume(ptr, ¶); if ( para && !p->align ) p->align = PARA; } return T(d); }