/* Examine the top of the file for series and extract the display * string, if present. FALSE is returned if the file appears to be * invalid or bereft of maps. */ static int readseriesheader(gameseries *series) { char buf[256]; int ch; int n; for (;;) { ch = fgetc(series->mapfp); if (ch == ';') { getnline(series->mapfp, buf, sizeof buf); if (*buf == ';') { for (n = 1 ; isspace(buf[n]) ; ++n) ; strncpy(series->name, buf + n, sizeof series->name - 1); series->name[sizeof series->name - 1] = '\0'; n = strlen(series->name); for (--n ; isspace(series->name[n]) ; --n) ; series->name[n + 1] = '\0'; return TRUE; } } else if (ch != '\n') break; } if (ch == EOF) { fclose(series->mapfp); series->mapfp = NULL; series->allmapsread = TRUE; return FALSE; } ungetc(ch, series->mapfp); return TRUE; }
/* exercise1-21 - Write a program entab that replaces strings of blanks * by the minimum number of tabs and blanks to achieve the same spacing. * Use the same tab stops as for detab. When either a tab or a single * blank would suffice to reach a tab stop, which should be given * preference? * * exercise1-21.c - a program that replaces strings of blanks by the * minimum number of tabs and blanks to achieve the same spacing. Tab * stops are given by parameter TABSTOPS. If only one space is seen * before a tab stop, then a space will be added to the output instead * of a tab. */ int main() { char linein[MAXLINE]; char lineout[MAXLINE]; while (getnline(linein, MAXLINE) > 0) { entab(linein, lineout); printf("%s", lineout); } return 0; }
/* Read a single map from the current position of fp and use it to * initialize the given gamesetup structure. Maps in the file are * separated by blank lines and/or lines beginning with a semicolon, * equal sign, or single quote. A semicolon appearing inside a line * in a map causes the remainder of the line to be ignored. */ static int readlevelmap(FILE *fp, gamesetup *game) { char buf[256]; char *p, *q; int badmap = FALSE; int y, x, n, ch; game->name[0] = '\0'; memset(game->map, EMPTY, sizeof game->map); game->xsize = 1; for (y = 1 ; y < MAXHEIGHT ; ++y) { ch = fgetc(fp); if (ch == EOF) { if (y > 1) break; else return FALSE; } else if (ch == '\n' || ch == ';' || ch == '=' || ch == '\'') { if (y > 1) { ungetc(ch, fp); break; } --y; if (ch == '\n') continue; n = getnline(fp, buf, sizeof buf); if (n < 0) return FALSE; if (ch == ';' && *buf == ';') { for (x = 1 ; isspace(buf[x]) ; ++x) ; n -= x; if (n >= (int)(sizeof game->name)) n = sizeof game->name - 1; memcpy(game->name, buf + x, n); for (--n ; isspace(game->name[n]) ; --n) ; game->name[n + 1] = '\0'; } continue; } buf[0] = ch; getnline(fp, buf + 1, sizeof buf - 1); if (badmap) continue; x = 1; p = buf; for ( ; x < MAXWIDTH && *p && *p != '\n' && *p != ';' ; ++x, ++p) { if (*p == '\t') { x |= 7; continue; } if (!(q = strchr(filecells, *p))) { fileerr("unrecognized character in level"); badmap = TRUE; break; } game->map[y * XSIZE + x] = q - filecells; } if (game->xsize <= x) { game->xsize = x + 1; if (game->xsize > MAXWIDTH) break; } } game->ysize = y + 1; if (game->ysize > MAXHEIGHT || game->xsize > MAXWIDTH) return fileerr("ignoring map which exceeds maximum dimensions"); if (!improvemap(game)) return FALSE; game->boxcount = 0; game->goalcount = 0; game->storecount = 0; for (n = 0 ; n < game->ysize * XSIZE ; ++n) { if (game->map[n] & PLAYER) game->start = n; else if (game->map[n] & BOX) { ++game->boxcount; if (game->map[n] & GOAL) ++game->storecount; } if (game->map[n] & GOAL) ++game->goalcount; } return TRUE; }
/* exercise1-23 - Write a program to remove all comments from a C * program. Don't forget to handle quoted strings and character * constants properly. C comments don't nest. * * exercise1-23.c - a program that removes all comments from a c program * */ void main() { char linein[MAXLINE]; char lineout[MAXLINE]; int prevchar; int incurs, outcurs; int insquote, indquote, inscomment, inmcomment, inescape; insquote = indquote = inscomment = inmcomment = inescape = 0; while (getnline(linein, MAXLINE) > 0) { incurs = outcurs = 0; prevchar = '\0'; while (linein[incurs] != '\n') { if (linein[incurs]=='\\' && prevchar!='\\') //handle escape sequences { inescape = 1; lineout[outcurs] = linein[incurs]; ++incurs; ++outcurs; } else if (linein[incurs]=='\'' && !inescape) //handle single quote { if (!insquote && !indquote && !inmcomment) { insquote = 1; lineout[outcurs] = linein[incurs]; ++incurs; ++outcurs; } else if (insquote) { insquote = 0; lineout[outcurs] = linein[incurs]; ++incurs; ++outcurs; } else { if (!inmcomment && !inscomment) lineout[outcurs] = linein[incurs]; ++incurs; ++outcurs; } } else if (linein[incurs]=='\"' && !inescape) //handle double quote { if (!insquote && !indquote && !inmcomment) { indquote = 1; lineout[outcurs] = linein[incurs]; ++incurs; ++outcurs; } else if (indquote) { indquote = 0; lineout[outcurs] = linein[incurs]; ++incurs; ++outcurs; } else { if (!inmcomment && !inscomment) lineout[outcurs] = linein[incurs]; ++incurs; ++outcurs; } } else if (linein[incurs]=='/' && linein[incurs+1]=='/' && !insquote && !indquote && !inscomment && !inmcomment) //start single comment { inscomment = 1; incurs = incurs + 2; } else if (linein[incurs]=='/' && linein[incurs+1]=='*' && !insquote && !indquote && !inscomment && !inmcomment) //start multi-line comment { inmcomment = 1; incurs = incurs + 2; } else if (linein[incurs]=='*' && linein[incurs+1]=='/' && inmcomment && !insquote && !indquote && !inscomment) //end multi-line comment { inmcomment = 0; incurs = incurs + 2; } else if (inscomment || inmcomment) { ++incurs; } else { lineout[outcurs] = linein[incurs]; ++incurs; ++outcurs; inescape = 0; } } lineout[outcurs] = '\n'; lineout[outcurs+1] = '\0'; printf("%s", lineout); inscomment = 0; } }