Als er nog meer op- aan merkingen zijn hoor ik het graag.
De globale variabelen die je nu hebt zijn niet nodig, want ze worden slechts binnen ��n functie gebruikt. Verder zou ik de waardes waartegen je vergelijkt constant maken, zodat de code iets makkelijker leesbaar is.
[cpp]
const int FILE_ERROR = -1;
const int OPEN_P = '(';
const int EQUALS = '=';
const int COLON = ':';
const int ASTERISK = '*';
const int SLASH = '/';
const int BACKSLASH = '\\';
const int UNDERSCORE = '_';
const int DOLLARSIGN = '$';
const int NEW_LINE = '\n';
[/cpp]
Voor het opvragen van de grootte volstaat het om de bestandsnaam op te geven:
[cpp]
int get_file_size(const char *file)
{
FILE *fp = fopen(file, "r");
if (fp == NULL) return FILE_ERROR;
/* ... */
}
[/cpp]
Gebruik maken van de standaard-functies van de taal kan het ook leesbaarder maken:
[cpp]
int isalph(const int c)
{
return (isalnum(c) || c == UNDERSCORE || c == DOLLARSIGN | c == BACKSLASH || c > 126);
}
[/cpp]
[cpp]
void minjs(const char *input, const char *output)
{
/* ... */
int qwoted = 0, qwoted_type = 0, regexp = 0; // deze variabelen worden alleen binnen de minjs functie gebruikt -> een globale scope is dus overbodig
}
[/cpp]
Verder kan de code ook compacter worden geschreven als je goed kijkt naar wat je hebt en waar je naartoe wilt. Ik ga niet de hele code herschrijven, maar ik geef je wel een idee van wat ik bedoel:
[cpp]
/*
/* RegExp? */
if (c == '/')
{
/* ... */
}
/* Single or multi line comment? */
if (c == '/' && qwoted == 0 && regexp == 0)
[/cpp]
-> beide hebben als voorwaarde c == SLASH
[cpp]
if (c == SLASH)
{
if (regexp && (prevchar != BACKSLASH || prevchar == preprechar))
{
regexp = 0;
}
if (qwoted == 0 && (prevchar == OPEN_P || prevchar == EQUALS || prevchar == COLON))
{
regexp = 1;
}
if (regexp == 0 && qwoted == 0)
{
/* ... */
}
}
[/cpp]
[cpp]
/* Quoted ? */
if (c == '\'' && qwoted_type != 0 && prevchar != '\\' && regexp == 0 || c == '\'' && qwoted_type != 0 && preprechar != 0 && prevchar == '\\' && preprechar == '\\' && regexp == 0 || c == '"' && qwoted_type != 1 && prevchar != '\\' && regexp == 0 || c == '"' && qwoted_type != 1 && preprechar != 0 && prevchar == '\\' && preprechar == '\\' && regexp == 0)
{
if (qwoted)
{
qwoted = 0;
}
else
{
/* Set quote type */
if (c == '"')
{
qwoted_type = 0;
}
else if (c == '\'')
{
qwoted_type = 1;
}
qwoted = 1;
}
}
[/cpp]
c == '\'' && qwoted_type != 0 && prevchar != '\\' && regexp == 0 ||
c == '\'' && qwoted_type != 0 && preprechar != 0 && prevchar == '\\' && preprechar == '\\' && regexp == 0 ||
c == '"' && qwoted_type != 1 && prevchar != '\\' && regexp == 0 ||
c == '"' && qwoted_type != 1 && preprechar != 0 && prevchar == '\\' && preprechar == '\\' && regexp == 0
Je kunt de code in drie stukken opdelen: regexp == 0 en (c == SINGLE_QUOTE && qwoted_type != 0 || c == DOUBLE_QUOTE && qwoted_type != 1) en (prevchar != BACKSLASH || prevchar == preprechar). Deze kun je samenvoegen tot:
[cpp]
if (regexp == 0 &&
(c == SINGLE_QUOTE && qwoted_type != 0 || c == DOUBLE_QUOTE && qwoted_type != 1) &&
(prevchar != BACKSLASH || prevchar == preprechar))
{
if (qwoted == 0)
qwoted_type = (c == SINGLE_QUOTE ? 1 : 0);
qwoted ^= 1;
}
[/cpp]
Als er geen argument wordt opgegeven en je controleert dan 'argv[1] == NULL', dan spreek je een element aan dat niet binnen het bereik van de array ligt. argv[argc-1] is immers het laatste element binnen de array, welke bij 1 argument dus gelijk is aan argv[0]. Via argc is het mogelijk te zien hoeveel argumenten er meegegeven zijn en aan de hand daarvan actie te ondernemen:
[cpp]
int main(int argc, char **argv)
{
int warns = 0; // deze variabele wordt in je huidige code alleen binnen je main functie gebruikt -> een globale scope is dus overbodig
if (argc == 2)
{
// if (strncmp(argv[1], "help", 4) == 0) -> toon help
// if (get_file_size(argv[1]) != FILE_ERROR) -> het argument voor de invoer is gegeven, maar niet voor de uitvoer
}
else if (argc == 3)
{
// de argumenten voor de invoer/uitvoer zijn opgegeven en kunnen dus op de voorwaarden gecontroleerd worden
// bericht dat het proces wordt gestart (stel dat je beslist om er een Windows-applicatie van te maken, dan heb je niks aan de printf functie die je nu gebruikt binnen minjs)
minjs(argv[1], argv[2]);
// bericht dat het proces voltooid is
}
else
{
// toon bericht over het programma gebruikt moet worden (volstaat ook indien er teveel argumenten worden meegegeven)
}
return 0;
}
[/cpp]
edit: de code is niet getest en ik zag een fout zitten welke ik verbeterd heb.
Laatst bewerkt: