static vString* extractInterpreter (FILE* input) { vString* const vLine = vStringNew (); const char* const line = readLine (vLine, input); vString* interpreter = NULL; if (line != NULL && line [0] == '#' && line [1] == '!') { /* "48.2.4.1 Specifying File Variables" of Emacs info: --------------------------------------------------- In shell scripts, the first line is used to identify the script interpreter, so you cannot put any local variables there. To accommodate this, Emacs looks for local variable specifications in the _second_ line if the first line specifies an interpreter. */ interpreter = extracEmacsModeAtFirstLine(input); if (!interpreter) { const char* const lastSlash = strrchr (line, '/'); const char *const cmd = lastSlash != NULL ? lastSlash+1 : line+2; interpreter = determineInterpreter (cmd); } } vStringDelete (vLine); return interpreter; }
static langType getInterpreterLanguage (const char *const fileName) { langType result = LANG_IGNORE; FILE* const fp = fopen (fileName, "r"); if (fp != NULL) { vString* const vLine = vStringNew (); const char* const line = readLine (vLine, fp); if (line != NULL && line [0] == '#' && line [1] == '!') { const char* const lastSlash = strrchr (line, '/'); const char *const cmd = lastSlash != NULL ? lastSlash+1 : line+2; vString* const interpreter = determineInterpreter (cmd); result = getExtensionLanguage (vStringValue (interpreter)); vStringDelete (interpreter); } vStringDelete (vLine); fclose (fp); } return result; }